Skip to content

Commit b9fadee

Browse files
jltoblergitster
authored andcommitted
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 c92abe7 (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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e1fbebe commit b9fadee

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

builtin/fetch.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1732,8 +1732,15 @@ static int do_fetch(struct transport *transport,
17321732
goto cleanup;
17331733

17341734
retcode = ref_transaction_commit(transaction, &err);
1735-
if (retcode)
1735+
if (retcode) {
1736+
/*
1737+
* Explicitly handle transaction cleanup to avoid
1738+
* aborting an already closed transaction.
1739+
*/
1740+
ref_transaction_free(transaction);
1741+
transaction = NULL;
17361742
goto cleanup;
1743+
}
17371744
}
17381745

17391746
commit_fetch_head(&fetch_head);

t/t5510-fetch.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,19 @@ test_expect_success 'fetch --atomic --append appends to FETCH_HEAD' '
345345
test_cmp expected atomic/.git/FETCH_HEAD
346346
'
347347

348+
test_expect_success REFFILES 'fetch --atomic fails transaction if reference locked' '
349+
test_when_finished "rm -rf upstream repo" &&
350+
351+
git init upstream &&
352+
git -C upstream commit --allow-empty -m 1 &&
353+
git -C upstream switch -c foobar &&
354+
git clone --mirror upstream repo &&
355+
git -C upstream commit --allow-empty -m 2 &&
356+
touch repo/refs/heads/foobar.lock &&
357+
358+
test_must_fail git -C repo fetch --atomic origin
359+
'
360+
348361
test_expect_success '--refmap="" ignores configured refspec' '
349362
cd "$TRASH_DIRECTORY" &&
350363
git clone "$D" remote-refs &&

0 commit comments

Comments
 (0)