]> git.ipfire.org Git - thirdparty/git.git/commitdiff
refs: return conflict error when checking packed refs
authorIvan Tse <ivan.tse1@gmail.com>
Sat, 4 May 2024 03:04:08 +0000 (03:04 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 6 May 2024 15:48:25 +0000 (08:48 -0700)
The TRANSACTION_NAME_CONFLICT error code refers to a failure to create a
ref due to a name conflict with another ref. An example of this is a
directory/file conflict such as ref names A/B and A.

"git fetch" uses this error code to more accurately describe the error
by recommending to the user that they try running "git remote prune" to
remove any old refs that are deleted by the remote which would clear up
any directory/file conflicts.

This helpful error message is not displayed when the conflicted ref is
stored in packed refs. This change fixes this by ensuring error return
code consistency in `lock_raw_ref`.

Signed-off-by: Ivan Tse <ivan.tse1@gmail.com>
Acked-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
refs/files-backend.c
t/t5510-fetch.sh

index a098d14ea00ed6db449e5d3cc8dff28594228977..97473f377d1d7c9772515273449dc7333d295384 100644 (file)
@@ -794,8 +794,10 @@ retry:
                 */
                if (refs_verify_refname_available(
                                    refs->packed_ref_store, refname,
-                                   extras, NULL, err))
+                                   extras, NULL, err)) {
+                       ret = TRANSACTION_NAME_CONFLICT;
                        goto error_return;
+               }
        }
 
        ret = 0;
index 33d34d5ae9e953e29f6dba8badb16922072cd76c..530369266fd227501288e5b7bd43a7d4e1f61651 100755 (executable)
@@ -1091,6 +1091,22 @@ test_expect_success 'branchname D/F conflict resolved by --prune' '
        test_cmp expect actual
 '
 
+test_expect_success 'branchname D/F conflict rejected with targeted error message' '
+       git clone . df-conflict-error &&
+       git branch dir_conflict &&
+       (
+               cd df-conflict-error &&
+               git update-ref refs/remotes/origin/dir_conflict/file HEAD &&
+               test_must_fail git fetch 2>err &&
+               test_grep "error: some local refs could not be updated; try running" err &&
+               test_grep " ${SQ}git remote prune origin${SQ} to remove any old, conflicting branches" err &&
+               git pack-refs --all &&
+               test_must_fail git fetch 2>err-packed &&
+               test_grep "error: some local refs could not be updated; try running" err-packed &&
+               test_grep " ${SQ}git remote prune origin${SQ} to remove any old, conflicting branches" err-packed
+       )
+'
+
 test_expect_success 'fetching a one-level ref works' '
        test_commit extra &&
        git reset --hard HEAD^ &&