зеркало из https://github.com/microsoft/git.git
Merge branch 'jk/refs-double-abort'
A corner case bug in the refs API has been corrected. * jk/refs-double-abort: refs/files-backend: don't look at an aborted transaction refs/files-backend: handle packed transaction prepare failure
This commit is contained in:
Коммит
2e08c892a7
|
@ -2701,18 +2701,32 @@ static int files_transaction_prepare(struct ref_store *ref_store,
|
|||
if (is_packed_transaction_needed(refs->packed_ref_store,
|
||||
packed_transaction)) {
|
||||
ret = ref_transaction_prepare(packed_transaction, err);
|
||||
/*
|
||||
* A failure during the prepare step will abort
|
||||
* itself, but not free. Do that now, and disconnect
|
||||
* from the files_transaction so it does not try to
|
||||
* abort us when we hit the cleanup code below.
|
||||
*/
|
||||
if (ret) {
|
||||
ref_transaction_free(packed_transaction);
|
||||
backend_data->packed_transaction = NULL;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We can skip rewriting the `packed-refs`
|
||||
* file. But we do need to leave it locked, so
|
||||
* that somebody else doesn't pack a reference
|
||||
* that we are trying to delete.
|
||||
*
|
||||
* We need to disconnect our transaction from
|
||||
* backend_data, since the abort (whether successful or
|
||||
* not) will free it.
|
||||
*/
|
||||
backend_data->packed_transaction = NULL;
|
||||
if (ref_transaction_abort(packed_transaction, err)) {
|
||||
ret = TRANSACTION_GENERIC_ERROR;
|
||||
goto cleanup;
|
||||
}
|
||||
backend_data->packed_transaction = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -618,4 +618,20 @@ test_expect_success 'delete fails cleanly if packed-refs file is locked' '
|
|||
test_cmp unchanged actual
|
||||
'
|
||||
|
||||
test_expect_success 'delete fails cleanly if packed-refs.new write fails' '
|
||||
# Setup and expectations are similar to the test above.
|
||||
prefix=refs/failed-packed-refs &&
|
||||
git update-ref $prefix/foo $C &&
|
||||
git pack-refs --all &&
|
||||
git update-ref $prefix/foo $D &&
|
||||
git for-each-ref $prefix >unchanged &&
|
||||
# This should not happen in practice, but it is an easy way to get a
|
||||
# reliable error (we open with create_tempfile(), which uses O_EXCL).
|
||||
: >.git/packed-refs.new &&
|
||||
test_when_finished "rm -f .git/packed-refs.new" &&
|
||||
test_must_fail git update-ref -d $prefix/foo &&
|
||||
git for-each-ref $prefix >actual &&
|
||||
test_cmp unchanged actual
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
Загрузка…
Ссылка в новой задаче