]> git.ipfire.org Git - thirdparty/git.git/commitdiff
refs: fix creation of reflog entries for symrefs
authorKarthik Nayak <karthik.188@gmail.com>
Thu, 23 Jan 2025 11:29:44 +0000 (12:29 +0100)
committerJunio C Hamano <gitster@pobox.com>
Thu, 23 Jan 2025 17:56:22 +0000 (09:56 -0800)
The commit 297c09eabb (refs: allow multiple reflog entries for the
same refname, 2024-12-16) added logic to exit early in
`lock_ref_for_update()` after obtaining the required lock. This was
added as a performance optimization on a false assumption that no
further processing was required for reflog-only updates.

However the assumption was wrong.  For a symref's reflog entry, the
update needs to be populated with the old_oid value, but the early
exit skipped this necessary step.

This caused a bug in Git 2.48 in the files backend where target
references of symrefs being updated would create a corrupted reflog
entry for the symref since the old_oid is not populated.

Everything the early exit skipped in the code path is necessary for
both regular and symbolic ref, so eliminate the mistaken
optimization, and also add a test to ensure that such an issue
doesn't arise in the future.

Reported-by: Nika Layzell <nika@thelayzells.com>
Co-authored-by: Jeff King <peff@peff.net>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
refs/files-backend.c
t/t1400-update-ref.sh

index 8953d1c6d37b13b0db701888b3db92fd87a68aaa..1c0e24a855acf97e9a2eec88700940a457819ded 100644 (file)
@@ -2611,9 +2611,6 @@ static int lock_ref_for_update(struct files_ref_store *refs,
 
        update->backend_data = lock;
 
-       if (update->flags & REF_LOG_ONLY)
-               goto out;
-
        if (update->type & REF_ISSYMREF) {
                if (update->flags & REF_NO_DEREF) {
                        /*
index e2316f1dd4c200df790ac639540d196df5c70c7b..29045aad43906fce3f64fb82ee98fb5f80d4796b 100755 (executable)
@@ -2068,4 +2068,13 @@ do
 
 done
 
+test_expect_success 'update-ref should also create reflog for HEAD' '
+       test_commit to-rewind &&
+       git rev-parse HEAD >expect &&
+       head=$(git symbolic-ref HEAD) &&
+       git update-ref --create-reflog "$head" HEAD~ &&
+       git rev-parse HEAD@{1} >actual &&
+       test_cmp expect actual
+'
+
 test_done