builtin/fetch: avoid aborting closed reference transaction
As part of the reference transaction commit phase, the transaction is
set to a closed state regardless of whether it was successful of not.
Attempting to abort a closed transaction via `ref_transaction_abort()`
results in a `BUG()`.
In c92abe71df
(builtin/fetch: fix leaking transaction with `--atomic`,
2024-08-22), logic to free a transaction after the commit phase is moved
to the centralized exit path. In cases where the transaction commit
failed, this results in a closed transaction being aborted and signaling
a bug.
Free the transaction and set it to NULL when the commit fails. This
allows the exit path to correctly handle the error without attempting to
abort the transaction.
Signed-off-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
main
parent
e1fbebe347
commit
b9fadeead7
|
@ -1732,8 +1732,15 @@ static int do_fetch(struct transport *transport,
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
retcode = ref_transaction_commit(transaction, &err);
|
retcode = ref_transaction_commit(transaction, &err);
|
||||||
if (retcode)
|
if (retcode) {
|
||||||
|
/*
|
||||||
|
* Explicitly handle transaction cleanup to avoid
|
||||||
|
* aborting an already closed transaction.
|
||||||
|
*/
|
||||||
|
ref_transaction_free(transaction);
|
||||||
|
transaction = NULL;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commit_fetch_head(&fetch_head);
|
commit_fetch_head(&fetch_head);
|
||||||
|
|
|
@ -345,6 +345,19 @@ test_expect_success 'fetch --atomic --append appends to FETCH_HEAD' '
|
||||||
test_cmp expected atomic/.git/FETCH_HEAD
|
test_cmp expected atomic/.git/FETCH_HEAD
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success REFFILES 'fetch --atomic fails transaction if reference locked' '
|
||||||
|
test_when_finished "rm -rf upstream repo" &&
|
||||||
|
|
||||||
|
git init upstream &&
|
||||||
|
git -C upstream commit --allow-empty -m 1 &&
|
||||||
|
git -C upstream switch -c foobar &&
|
||||||
|
git clone --mirror upstream repo &&
|
||||||
|
git -C upstream commit --allow-empty -m 2 &&
|
||||||
|
touch repo/refs/heads/foobar.lock &&
|
||||||
|
|
||||||
|
test_must_fail git -C repo fetch --atomic origin
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success '--refmap="" ignores configured refspec' '
|
test_expect_success '--refmap="" ignores configured refspec' '
|
||||||
cd "$TRASH_DIRECTORY" &&
|
cd "$TRASH_DIRECTORY" &&
|
||||||
git clone "$D" remote-refs &&
|
git clone "$D" remote-refs &&
|
||||||
|
|
Loading…
Reference in New Issue