fetch: set remote/HEAD if it does not exist

When cloning a repository remote/HEAD is created, but when the user creates a repository with git init, and later adds a remote, remote/HEAD is only created if the user explicitly runs a variant of "remote set-head". Attempt to set remote/HEAD during fetch, if the user does not have it already set. Silently ignore any errors. Signed-off-by: Bence Ferdinandy <bence@ferdinandy.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Bence Ferdinandy committed Nov 22, 2024 at 13:28 UTC 3f763ddf28d28fe63963991513c8db4045eabadc
12 files changed +203 -17
builtin/fetch.c
+68
@@ -1577,6 +1577,66 @@ static int backfill_tags(struct display_state *display_state,
1577 return retcode;
1578 }
1579
1580 +static const char *strip_refshead(const char *name){
1581 + skip_prefix(name, "refs/heads/", &name);
1582 + return name;
1583 +}
1584 +
1585 +static int set_head(const struct ref *remote_refs)
1586 +{
1587 + int result = 0;
1588 + struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT;
1589 + const char *remote = gtransport->remote->name;
1590 + char *head_name = NULL;
1591 + struct ref *ref, *matches;
1592 + struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map;
1593 + struct refspec_item refspec = {
1594 + .force = 0,
1595 + .pattern = 1,
1596 + .src = (char *) "refs/heads/*",
1597 + .dst = (char *) "refs/heads/*",
1598 + };
1599 + struct string_list heads = STRING_LIST_INIT_DUP;
1600 + struct ref_store *refs = get_main_ref_store(the_repository);
1601 +
1602 + get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);
1603 + matches = guess_remote_head(find_ref_by_name(remote_refs, "HEAD"),
1604 + fetch_map, 1);
1605 + for (ref = matches; ref; ref = ref->next) {
1606 + string_list_append(&heads, strip_refshead(ref->name));
1607 + }
1608 +
1609 +
1610 + if (!heads.nr)
1611 + result = 1;
1612 + else if (heads.nr > 1)
1613 + result = 1;
1614 + else
1615 + head_name = xstrdup(heads.items[0].string);
1616 +
1617 + if (!head_name)
1618 + goto cleanup;
1619 + strbuf_addf(&b_head, "refs/remotes/%s/HEAD", remote);
1620 + strbuf_addf(&b_remote_head, "refs/remotes/%s/%s", remote, head_name);
1621 + /* make sure it's valid */
1622 + if (!refs_ref_exists(refs, b_remote_head.buf)) {
1623 + result = 1;
1624 + goto cleanup;
1625 + }
1626 + if (refs_update_symref_extended(refs, b_head.buf, b_remote_head.buf,
1627 + "fetch", NULL, 1))
1628 + result = 1;
1629 +
1630 +cleanup:
1631 + free(head_name);
1632 + free_refs(fetch_map);
1633 + free_refs(matches);
1634 + string_list_clear(&heads, 0);
1635 + strbuf_release(&b_head);
1636 + strbuf_release(&b_remote_head);
1637 + return result;
1638 +}
1639 +
1640 static int do_fetch(struct transport *transport,
1641 struct refspec *rs,
1642 const struct fetch_config *config)
@@ -1646,6 +1706,8 @@ static int do_fetch(struct transport *transport,
1706 "refs/tags/");
1707 }
1708
1709 + strvec_push(&transport_ls_refs_options.ref_prefixes, "HEAD");
1710 +
1711 if (must_list_refs) {
1712 trace2_region_enter("fetch", "remote_refs", the_repository);
1713 remote_refs = transport_get_remote_refs(transport,
@@ -1790,6 +1852,12 @@ static int do_fetch(struct transport *transport,
1852 "you need to specify exactly one branch with the --set-upstream option"));
1853 }
1854 }
1855 + if (set_head(remote_refs))
1856 + ;
1857 + /*
1858 + * Way too many cases where this can go wrong
1859 + * so let's just fail silently for now.
1860 + */
1861
1862 cleanup:
1863 if (retcode) {
t/t4207-log-decoration-colors.sh
+2 -1
@@ -59,7 +59,8 @@ ${c_reset}${c_tag}tag: ${c_reset}${c_tag}v1.0${c_reset}${c_commit}, \
59 ${c_reset}${c_tag}tag: ${c_reset}${c_tag}B${c_reset}${c_commit})${c_reset} B
60 ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\
61 ${c_tag}tag: ${c_reset}${c_tag}A1${c_reset}${c_commit}, \
62 -${c_reset}${c_remoteBranch}other/main${c_reset}${c_commit})${c_reset} A1
62 +${c_reset}${c_remoteBranch}other/main${c_reset}${c_commit}, \
63 +${c_reset}${c_remoteBranch}other/HEAD${c_reset}${c_commit})${c_reset} A1
64 ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\
65 ${c_stash}refs/stash${c_reset}${c_commit})${c_reset} On main: Changes to A.t
66 ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\
t/t5505-remote.sh
+15 -6
@@ -74,7 +74,7 @@ test_expect_success 'add another remote' '
74 cd test &&
75 git remote add -f second ../two &&
76 tokens_match "origin second" "$(git remote)" &&
77 - check_tracking_branch second main side another &&
77 + check_tracking_branch second main side another HEAD &&
78 git for-each-ref "--format=%(refname)" refs/remotes |
79 sed -e "/^refs\/remotes\/origin\//d" \
80 -e "/^refs\/remotes\/second\//d" >actual &&
@@ -500,7 +500,7 @@ test_expect_success 'set-head --auto has no problem w/multiple HEADs' '
500 cd test &&
501 git fetch two "refs/heads/*:refs/remotes/two/*" &&
502 git remote set-head --auto two >output 2>&1 &&
503 - echo "${SQ}two/HEAD${SQ} is now created and points to ${SQ}main${SQ}" >expect &&
503 + echo "${SQ}two/HEAD${SQ} is unchanged and points to ${SQ}main${SQ}" >expect &&
504 test_cmp expect output
505 )
506 '
@@ -788,8 +788,10 @@ test_expect_success 'reject --no-no-tags' '
788 '
789
790 cat >one/expect <<\EOF
791 + apis/HEAD -> apis/main
792 apis/main
793 apis/side
794 + drosophila/HEAD -> drosophila/main
795 drosophila/another
796 drosophila/main
797 drosophila/side
@@ -807,11 +809,14 @@ test_expect_success 'update' '
809 '
810
811 cat >one/expect <<\EOF
812 + drosophila/HEAD -> drosophila/main
813 drosophila/another
814 drosophila/main
815 drosophila/side
816 + manduca/HEAD -> manduca/main
817 manduca/main
818 manduca/side
819 + megaloprepus/HEAD -> megaloprepus/main
820 megaloprepus/main
821 megaloprepus/side
822 EOF
@@ -819,7 +824,7 @@ EOF
824 test_expect_success 'update with arguments' '
825 (
826 cd one &&
822 - for b in $(git branch -r)
827 + for b in $(git branch -r | grep -v HEAD)
828 do
829 git branch -r -d $b || exit 1
830 done &&
@@ -851,10 +856,13 @@ test_expect_success 'update --prune' '
856 '
857
858 cat >one/expect <<-\EOF
859 + apis/HEAD -> apis/main
860 apis/main
861 apis/side
862 + manduca/HEAD -> manduca/main
863 manduca/main
864 manduca/side
865 + megaloprepus/HEAD -> megaloprepus/main
866 megaloprepus/main
867 megaloprepus/side
868 EOF
@@ -862,7 +870,7 @@ EOF
870 test_expect_success 'update default' '
871 (
872 cd one &&
865 - for b in $(git branch -r)
873 + for b in $(git branch -r | grep -v HEAD)
874 do
875 git branch -r -d $b || exit 1
876 done &&
@@ -874,6 +882,7 @@ test_expect_success 'update default' '
882 '
883
884 cat >one/expect <<\EOF
885 + drosophila/HEAD -> drosophila/main
886 drosophila/another
887 drosophila/main
888 drosophila/side
@@ -882,7 +891,7 @@ EOF
891 test_expect_success 'update default (overridden, with funny whitespace)' '
892 (
893 cd one &&
885 - for b in $(git branch -r)
894 + for b in $(git branch -r | grep -v HEAD)
895 do
896 git branch -r -d $b || exit 1
897 done &&
@@ -896,7 +905,7 @@ test_expect_success 'update default (overridden, with funny whitespace)' '
905 test_expect_success 'update (with remotes.default defined)' '
906 (
907 cd one &&
899 - for b in $(git branch -r)
908 + for b in $(git branch -r | grep -v HEAD)
909 do
910 git branch -r -d $b || exit 1
911 done &&
t/t5510-fetch.sh
+24
@@ -75,6 +75,30 @@ test_expect_success "fetch test for-merge" '
75 cut -f -2 .git/FETCH_HEAD >actual &&
76 test_cmp expected actual'
77
78 +test_expect_success "fetch test remote HEAD" '
79 + cd "$D" &&
80 + cd two &&
81 + git fetch &&
82 + git rev-parse --verify refs/remotes/origin/HEAD &&
83 + git rev-parse --verify refs/remotes/origin/main &&
84 + head=$(git rev-parse refs/remotes/origin/HEAD) &&
85 + branch=$(git rev-parse refs/remotes/origin/main) &&
86 + test "z$head" = "z$branch"'
87 +
88 +test_expect_success "fetch test remote HEAD change" '
89 + cd "$D" &&
90 + cd two &&
91 + git switch -c other &&
92 + git push -u origin other &&
93 + git rev-parse --verify refs/remotes/origin/HEAD &&
94 + git rev-parse --verify refs/remotes/origin/main &&
95 + git rev-parse --verify refs/remotes/origin/other &&
96 + git remote set-head origin other &&
97 + git fetch &&
98 + head=$(git rev-parse refs/remotes/origin/HEAD) &&
99 + branch=$(git rev-parse refs/remotes/origin/other) &&
100 + test "z$head" = "z$branch"'
101 +
102 test_expect_success 'fetch --prune on its own works as expected' '
103 cd "$D" &&
104 git clone . prune &&
t/t5512-ls-remote.sh
+2
@@ -293,6 +293,8 @@ test_expect_success 'ls-remote with filtered symref (refname)' '
293 cat >expect <<-EOF &&
294 ref: refs/heads/main HEAD
295 $rev HEAD
296 + ref: refs/remotes/origin/main refs/remotes/origin/HEAD
297 + $rev refs/remotes/origin/HEAD
298 EOF
299 git ls-remote --symref . HEAD >actual &&
300 test_cmp expect actual
t/t5514-fetch-multiple.sh
+15 -2
@@ -45,14 +45,17 @@ test_expect_success setup '
45 '
46
47 cat > test/expect << EOF
48 + one/HEAD -> one/main
49 one/main
50 one/side
51 origin/HEAD -> origin/main
52 origin/main
53 origin/side
54 + three/HEAD -> three/main
55 three/another
56 three/main
57 three/side
58 + two/HEAD -> two/main
59 two/another
60 two/main
61 two/side
@@ -97,6 +100,7 @@ cat > expect << EOF
100 origin/HEAD -> origin/main
101 origin/main
102 origin/side
103 + three/HEAD -> three/main
104 three/another
105 three/main
106 three/side
@@ -112,8 +116,10 @@ test_expect_success 'git fetch --multiple (but only one remote)' '
116 '
117
118 cat > expect << EOF
119 + one/HEAD -> one/main
120 one/main
121 one/side
122 + two/HEAD -> two/main
123 two/another
124 two/main
125 two/side
@@ -141,7 +147,7 @@ test_expect_success 'git fetch --multiple (bad remote names)' '
147
148 test_expect_success 'git fetch --all (skipFetchAll)' '
149 (cd test4 &&
144 - for b in $(git branch -r)
150 + for b in $(git branch -r | grep -v HEAD)
151 do
152 git branch -r -d $b || exit 1
153 done &&
@@ -153,11 +159,14 @@ test_expect_success 'git fetch --all (skipFetchAll)' '
159 '
160
161 cat > expect << EOF
162 + one/HEAD -> one/main
163 one/main
164 one/side
165 + three/HEAD -> three/main
166 three/another
167 three/main
168 three/side
169 + two/HEAD -> two/main
170 two/another
171 two/main
172 two/side
@@ -165,7 +174,7 @@ EOF
174
175 test_expect_success 'git fetch --multiple (ignoring skipFetchAll)' '
176 (cd test4 &&
168 - for b in $(git branch -r)
177 + for b in $(git branch -r | grep -v HEAD)
178 do
179 git branch -r -d $b || exit 1
180 done &&
@@ -221,14 +230,17 @@ test_expect_success 'git fetch --multiple --jobs=0 picks a default' '
230
231 create_fetch_all_expect () {
232 cat >expect <<-\EOF
233 + one/HEAD -> one/main
234 one/main
235 one/side
236 origin/HEAD -> origin/main
237 origin/main
238 origin/side
239 + three/HEAD -> three/main
240 three/another
241 three/main
242 three/side
243 + two/HEAD -> two/main
244 two/another
245 two/main
246 two/side
@@ -265,6 +277,7 @@ test_expect_success 'git fetch (fetch all remotes with fetch.all = true)' '
277
278 create_fetch_one_expect () {
279 cat >expect <<-\EOF
280 + one/HEAD -> one/main
281 one/main
282 one/side
283 origin/HEAD -> origin/main
t/t5516-fetch-push.sh
+2 -1
@@ -1395,7 +1395,8 @@ test_expect_success 'fetch follows tags by default' '
1395 git tag -m "annotated" tag &&
1396 git for-each-ref >tmp1 &&
1397 sed -n "p; s|refs/heads/main$|refs/remotes/origin/main|p" tmp1 |
1398 - sort -k 3 >../expect
1398 + sed -n "p; s|refs/heads/main$|refs/remotes/origin/HEAD|p" |
1399 + sort -k 4 >../expect
1400 ) &&
1401 test_when_finished "rm -rf dst" &&
1402 git init dst &&
t/t5527-fetch-odd-refs.sh
+2 -1
@@ -52,7 +52,8 @@ test_expect_success LONG_REF 'fetch handles extremely long refname' '
52 long
53 main
54 EOF
55 - git for-each-ref --format="%(subject)" refs/remotes/long >actual &&
55 + git for-each-ref --format="%(subject)" refs/remotes/long \
56 + --exclude=refs/remotes/long/HEAD >actual &&
57 test_cmp expect actual
58 '
59
t/t7900-maintenance.sh
+2 -1
@@ -328,7 +328,8 @@ test_expect_success 'incremental-repack task' '
328
329 # Delete refs that have not been repacked in these packs.
330 git for-each-ref --format="delete %(refname)" \
331 - refs/prefetch refs/tags refs/remotes >refs &&
331 + refs/prefetch refs/tags refs/remotes \
332 + --exclude=refs/remotes/*/HEAD >refs &&
333 git update-ref --stdin <refs &&
334
335 # Replace the object directory with this pack layout.
t/t9210-scalar.sh
+3 -2
@@ -150,7 +150,8 @@ test_expect_success 'scalar clone' '
150 "$(pwd)" &&
151
152 git for-each-ref --format="%(refname)" refs/remotes/origin/ >actual &&
153 - echo "refs/remotes/origin/parallel" >expect &&
153 + echo "refs/remotes/origin/HEAD" >>expect &&
154 + echo "refs/remotes/origin/parallel" >>expect &&
155 test_cmp expect actual &&
156
157 test_path_is_missing 1/2 &&
@@ -219,7 +220,7 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' '
220 done
221 '
222
222 - test_expect_success 'scalar reconfigure --all with detached HEADs' '
223 +test_expect_success 'scalar reconfigure --all with detached HEADs' '
224 repos="two three four" &&
225 for num in $repos
226 do
t/t9211-scalar-clone.sh
+3 -3
@@ -31,7 +31,7 @@ test_expect_success 'set up repository to clone' '
31 )
32 '
33
34 -cleanup_clone () {
34 +cleanup_clone() {
35 rm -rf "$1"
36 }
37
@@ -127,7 +127,7 @@ test_expect_success '--single-branch clones HEAD only' '
127 (
128 cd $enlistment/src &&
129 git for-each-ref refs/remotes/origin >out &&
130 - test_line_count = 1 out &&
130 + test_line_count = 2 out &&
131 grep "refs/remotes/origin/base" out
132 ) &&
133
@@ -141,7 +141,7 @@ test_expect_success '--no-single-branch clones all branches' '
141 (
142 cd $enlistment/src &&
143 git for-each-ref refs/remotes/origin >out &&
144 - test_line_count = 2 out &&
144 + test_line_count = 3 out &&
145 grep "refs/remotes/origin/base" out &&
146 grep "refs/remotes/origin/parallel" out
147 ) &&
t/t9902-completion.sh
+65
@@ -658,6 +658,7 @@ test_expect_success '__git_refs - simple' '
658 HEAD
659 main
660 matching-branch
661 + other/HEAD
662 other/branch-in-other
663 other/main-in-other
664 matching-tag
@@ -673,6 +674,7 @@ test_expect_success '__git_refs - full refs' '
674 cat >expected <<-EOF &&
675 refs/heads/main
676 refs/heads/matching-branch
677 + refs/remotes/other/HEAD
678 refs/remotes/other/branch-in-other
679 refs/remotes/other/main-in-other
680 refs/tags/matching-tag
@@ -729,6 +731,7 @@ test_expect_success '__git_refs - remote on local file system - full refs' '
731 test_expect_success '__git_refs - configured remote' '
732 cat >expected <<-EOF &&
733 HEAD
734 + HEAD
735 branch-in-other
736 main-in-other
737 EOF
@@ -756,6 +759,7 @@ test_expect_success '__git_refs - configured remote - full refs' '
759 test_expect_success '__git_refs - configured remote - repo given on the command line' '
760 cat >expected <<-EOF &&
761 HEAD
762 + HEAD
763 branch-in-other
764 main-in-other
765 EOF
@@ -787,6 +791,7 @@ test_expect_success '__git_refs - configured remote - full refs - repo given on
791 test_expect_success '__git_refs - configured remote - remote name matches a directory' '
792 cat >expected <<-EOF &&
793 HEAD
794 + HEAD
795 branch-in-other
796 main-in-other
797 EOF
@@ -875,12 +880,14 @@ test_expect_success '__git_refs - unique remote branches for git checkout DWIMer
880 HEAD
881 main
882 matching-branch
883 + other/HEAD
884 other/ambiguous
885 other/branch-in-other
886 other/main-in-other
887 remote/ambiguous
888 remote/branch-in-remote
889 matching-tag
890 + HEAD
891 branch-in-other
892 branch-in-remote
893 main-in-other
@@ -904,6 +911,7 @@ test_expect_success '__git_refs - after --opt=' '
911 HEAD
912 main
913 matching-branch
914 + other/HEAD
915 other/branch-in-other
916 other/main-in-other
917 matching-tag
@@ -919,6 +927,7 @@ test_expect_success '__git_refs - after --opt= - full refs' '
927 cat >expected <<-EOF &&
928 refs/heads/main
929 refs/heads/matching-branch
930 + refs/remotes/other/HEAD
931 refs/remotes/other/branch-in-other
932 refs/remotes/other/main-in-other
933 refs/tags/matching-tag
@@ -935,6 +944,7 @@ test_expect_success '__git refs - excluding refs' '
944 ^HEAD
945 ^main
946 ^matching-branch
947 + ^other/HEAD
948 ^other/branch-in-other
949 ^other/main-in-other
950 ^matching-tag
@@ -950,6 +960,7 @@ test_expect_success '__git refs - excluding full refs' '
960 cat >expected <<-EOF &&
961 ^refs/heads/main
962 ^refs/heads/matching-branch
963 + ^refs/remotes/other/HEAD
964 ^refs/remotes/other/branch-in-other
965 ^refs/remotes/other/main-in-other
966 ^refs/tags/matching-tag
@@ -975,6 +986,7 @@ test_expect_success '__git_refs - do not filter refs unless told so' '
986 main
987 matching-branch
988 matching/branch
989 + other/HEAD
990 other/branch-in-other
991 other/main-in-other
992 other/matching/branch-in-other
@@ -1095,6 +1107,7 @@ test_expect_success '__git_complete_refs - simple' '
1107 HEAD Z
1108 main Z
1109 matching-branch Z
1110 + other/HEAD Z
1111 other/branch-in-other Z
1112 other/main-in-other Z
1113 matching-tag Z
@@ -1123,6 +1136,7 @@ test_expect_success '__git_complete_refs - matching' '
1136 test_expect_success '__git_complete_refs - remote' '
1137 sed -e "s/Z$//" >expected <<-EOF &&
1138 HEAD Z
1139 + HEAD Z
1140 branch-in-other Z
1141 main-in-other Z
1142 EOF
@@ -1139,9 +1153,11 @@ test_expect_success '__git_complete_refs - track' '
1153 HEAD Z
1154 main Z
1155 matching-branch Z
1156 + other/HEAD Z
1157 other/branch-in-other Z
1158 other/main-in-other Z
1159 matching-tag Z
1160 + HEAD Z
1161 branch-in-other Z
1162 main-in-other Z
1163 EOF
@@ -1184,6 +1200,7 @@ test_expect_success '__git_complete_refs - suffix' '
1200 HEAD.
1201 main.
1202 matching-branch.
1203 + other/HEAD.
1204 other/branch-in-other.
1205 other/main-in-other.
1206 matching-tag.
@@ -1199,6 +1216,7 @@ test_expect_success '__git_complete_refs - suffix' '
1216 test_expect_success '__git_complete_fetch_refspecs - simple' '
1217 sed -e "s/Z$//" >expected <<-EOF &&
1218 HEAD:HEAD Z
1219 + HEAD:HEAD Z
1220 branch-in-other:branch-in-other Z
1221 main-in-other:main-in-other Z
1222 EOF
@@ -1225,6 +1243,7 @@ test_expect_success '__git_complete_fetch_refspecs - matching' '
1243 test_expect_success '__git_complete_fetch_refspecs - prefix' '
1244 sed -e "s/Z$//" >expected <<-EOF &&
1245 +HEAD:HEAD Z
1246 + +HEAD:HEAD Z
1247 +branch-in-other:branch-in-other Z
1248 +main-in-other:main-in-other Z
1249 EOF
@@ -1289,6 +1308,7 @@ test_expect_success '__git_complete_worktree_paths with -C' '
1308
1309 test_expect_success 'git switch - with no options, complete local branches and unique remote branch names for DWIM logic' '
1310 test_completion "git switch " <<-\EOF
1311 + HEAD Z
1312 branch-in-other Z
1313 main Z
1314 main-in-other Z
@@ -1435,11 +1455,13 @@ test_expect_success 'git-bisect - existing view subcommand is recognized and ena
1455 test_expect_success 'git checkout - completes refs and unique remote branches for DWIM' '
1456 test_completion "git checkout " <<-\EOF
1457 HEAD Z
1458 + HEAD Z
1459 branch-in-other Z
1460 main Z
1461 main-in-other Z
1462 matching-branch Z
1463 matching-tag Z
1464 + other/HEAD Z
1465 other/branch-in-other Z
1466 other/main-in-other Z
1467 EOF
@@ -1461,6 +1483,7 @@ test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, compl
1483
1484 test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' '
1485 GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch --guess " <<-\EOF
1486 + HEAD Z
1487 branch-in-other Z
1488 main Z
1489 main-in-other Z
@@ -1470,6 +1493,7 @@ test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_G
1493
1494 test_expect_success 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' '
1495 test_completion "git switch --no-guess --guess " <<-\EOF
1496 + HEAD Z
1497 branch-in-other Z
1498 main Z
1499 main-in-other Z
@@ -1490,6 +1514,7 @@ test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only complete
1514 main Z
1515 matching-branch Z
1516 matching-tag Z
1517 + other/HEAD Z
1518 other/branch-in-other Z
1519 other/main-in-other Z
1520 EOF
@@ -1498,11 +1523,13 @@ test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only complete
1523 test_expect_success 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, complete refs and unique remote branches for DWIM' '
1524 GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout --guess " <<-\EOF
1525 HEAD Z
1526 + HEAD Z
1527 branch-in-other Z
1528 main Z
1529 main-in-other Z
1530 matching-branch Z
1531 matching-tag Z
1532 + other/HEAD Z
1533 other/branch-in-other Z
1534 other/main-in-other Z
1535 EOF
@@ -1514,6 +1541,7 @@ test_expect_success 'git checkout - with --no-guess, only completes refs' '
1541 main Z
1542 matching-branch Z
1543 matching-tag Z
1544 + other/HEAD Z
1545 other/branch-in-other Z
1546 other/main-in-other Z
1547 EOF
@@ -1522,11 +1550,13 @@ test_expect_success 'git checkout - with --no-guess, only completes refs' '
1550 test_expect_success 'git checkout - a later --guess overrides previous --no-guess, complete refs and unique remote branches for DWIM' '
1551 test_completion "git checkout --no-guess --guess " <<-\EOF
1552 HEAD Z
1553 + HEAD Z
1554 branch-in-other Z
1555 main Z
1556 main-in-other Z
1557 matching-branch Z
1558 matching-tag Z
1559 + other/HEAD Z
1560 other/branch-in-other Z
1561 other/main-in-other Z
1562 EOF
@@ -1538,6 +1568,7 @@ test_expect_success 'git checkout - a later --no-guess overrides previous --gues
1568 main Z
1569 matching-branch Z
1570 matching-tag Z
1571 + other/HEAD Z
1572 other/branch-in-other Z
1573 other/main-in-other Z
1574 EOF
@@ -1550,6 +1581,7 @@ test_expect_success 'git checkout - with checkout.guess = false, only completes
1581 main Z
1582 matching-branch Z
1583 matching-tag Z
1584 + other/HEAD Z
1585 other/branch-in-other Z
1586 other/main-in-other Z
1587 EOF
@@ -1559,11 +1591,13 @@ test_expect_success 'git checkout - with checkout.guess = true, completes refs a
1591 test_config checkout.guess true &&
1592 test_completion "git checkout " <<-\EOF
1593 HEAD Z
1594 + HEAD Z
1595 branch-in-other Z
1596 main Z
1597 main-in-other Z
1598 matching-branch Z
1599 matching-tag Z
1600 + other/HEAD Z
1601 other/branch-in-other Z
1602 other/main-in-other Z
1603 EOF
@@ -1573,11 +1607,13 @@ test_expect_success 'git checkout - a later --guess overrides previous checkout.
1607 test_config checkout.guess false &&
1608 test_completion "git checkout --guess " <<-\EOF
1609 HEAD Z
1610 + HEAD Z
1611 branch-in-other Z
1612 main Z
1613 main-in-other Z
1614 matching-branch Z
1615 matching-tag Z
1616 + other/HEAD Z
1617 other/branch-in-other Z
1618 other/main-in-other Z
1619 EOF
@@ -1590,6 +1626,7 @@ test_expect_success 'git checkout - a later --no-guess overrides previous checko
1626 main Z
1627 matching-branch Z
1628 matching-tag Z
1629 + other/HEAD Z
1630 other/branch-in-other Z
1631 other/main-in-other Z
1632 EOF
@@ -1601,6 +1638,7 @@ test_expect_success 'git switch - with --detach, complete all references' '
1638 main Z
1639 matching-branch Z
1640 matching-tag Z
1641 + other/HEAD Z
1642 other/branch-in-other Z
1643 other/main-in-other Z
1644 EOF
@@ -1612,6 +1650,7 @@ test_expect_success 'git checkout - with --detach, complete only references' '
1650 main Z
1651 matching-branch Z
1652 matching-tag Z
1653 + other/HEAD Z
1654 other/branch-in-other Z
1655 other/main-in-other Z
1656 EOF
@@ -1783,6 +1822,7 @@ test_expect_success 'git switch - with -d, complete all references' '
1822 main Z
1823 matching-branch Z
1824 matching-tag Z
1825 + other/HEAD Z
1826 other/branch-in-other Z
1827 other/main-in-other Z
1828 EOF
@@ -1794,6 +1834,7 @@ test_expect_success 'git checkout - with -d, complete only references' '
1834 main Z
1835 matching-branch Z
1836 matching-tag Z
1837 + other/HEAD Z
1838 other/branch-in-other Z
1839 other/main-in-other Z
1840 EOF
@@ -1801,10 +1842,12 @@ test_expect_success 'git checkout - with -d, complete only references' '
1842
1843 test_expect_success 'git switch - with --track, complete only remote branches' '
1844 test_completion "git switch --track " <<-\EOF &&
1845 + other/HEAD Z
1846 other/branch-in-other Z
1847 other/main-in-other Z
1848 EOF
1849 test_completion "git switch -t " <<-\EOF
1850 + other/HEAD Z
1851 other/branch-in-other Z
1852 other/main-in-other Z
1853 EOF
@@ -1812,10 +1855,12 @@ test_expect_success 'git switch - with --track, complete only remote branches' '
1855
1856 test_expect_success 'git checkout - with --track, complete only remote branches' '
1857 test_completion "git checkout --track " <<-\EOF &&
1858 + other/HEAD Z
1859 other/branch-in-other Z
1860 other/main-in-other Z
1861 EOF
1862 test_completion "git checkout -t " <<-\EOF
1863 + other/HEAD Z
1864 other/branch-in-other Z
1865 other/main-in-other Z
1866 EOF
@@ -1834,6 +1879,7 @@ test_expect_success 'git checkout - with --no-track, complete only local referen
1879 main Z
1880 matching-branch Z
1881 matching-tag Z
1882 + other/HEAD Z
1883 other/branch-in-other Z
1884 other/main-in-other Z
1885 EOF
@@ -1845,6 +1891,7 @@ test_expect_success 'git switch - with -c, complete all references' '
1891 main Z
1892 matching-branch Z
1893 matching-tag Z
1894 + other/HEAD Z
1895 other/branch-in-other Z
1896 other/main-in-other Z
1897 EOF
@@ -1856,6 +1903,7 @@ test_expect_success 'git switch - with -C, complete all references' '
1903 main Z
1904 matching-branch Z
1905 matching-tag Z
1906 + other/HEAD Z
1907 other/branch-in-other Z
1908 other/main-in-other Z
1909 EOF
@@ -1867,6 +1915,7 @@ test_expect_success 'git switch - with -c and --track, complete all references'
1915 main Z
1916 matching-branch Z
1917 matching-tag Z
1918 + other/HEAD Z
1919 other/branch-in-other Z
1920 other/main-in-other Z
1921 EOF
@@ -1878,6 +1927,7 @@ test_expect_success 'git switch - with -C and --track, complete all references'
1927 main Z
1928 matching-branch Z
1929 matching-tag Z
1930 + other/HEAD Z
1931 other/branch-in-other Z
1932 other/main-in-other Z
1933 EOF
@@ -1889,6 +1939,7 @@ test_expect_success 'git switch - with -c and --no-track, complete all reference
1939 main Z
1940 matching-branch Z
1941 matching-tag Z
1942 + other/HEAD Z
1943 other/branch-in-other Z
1944 other/main-in-other Z
1945 EOF
@@ -1900,6 +1951,7 @@ test_expect_success 'git switch - with -C and --no-track, complete all reference
1951 main Z
1952 matching-branch Z
1953 matching-tag Z
1954 + other/HEAD Z
1955 other/branch-in-other Z
1956 other/main-in-other Z
1957 EOF
@@ -1911,6 +1963,7 @@ test_expect_success 'git checkout - with -b, complete all references' '
1963 main Z
1964 matching-branch Z
1965 matching-tag Z
1966 + other/HEAD Z
1967 other/branch-in-other Z
1968 other/main-in-other Z
1969 EOF
@@ -1922,6 +1975,7 @@ test_expect_success 'git checkout - with -B, complete all references' '
1975 main Z
1976 matching-branch Z
1977 matching-tag Z
1978 + other/HEAD Z
1979 other/branch-in-other Z
1980 other/main-in-other Z
1981 EOF
@@ -1933,6 +1987,7 @@ test_expect_success 'git checkout - with -b and --track, complete all references
1987 main Z
1988 matching-branch Z
1989 matching-tag Z
1990 + other/HEAD Z
1991 other/branch-in-other Z
1992 other/main-in-other Z
1993 EOF
@@ -1944,6 +1999,7 @@ test_expect_success 'git checkout - with -B and --track, complete all references
1999 main Z
2000 matching-branch Z
2001 matching-tag Z
2002 + other/HEAD Z
2003 other/branch-in-other Z
2004 other/main-in-other Z
2005 EOF
@@ -1955,6 +2011,7 @@ test_expect_success 'git checkout - with -b and --no-track, complete all referen
2011 main Z
2012 matching-branch Z
2013 matching-tag Z
2014 + other/HEAD Z
2015 other/branch-in-other Z
2016 other/main-in-other Z
2017 EOF
@@ -1966,6 +2023,7 @@ test_expect_success 'git checkout - with -B and --no-track, complete all referen
2023 main Z
2024 matching-branch Z
2025 matching-tag Z
2026 + other/HEAD Z
2027 other/branch-in-other Z
2028 other/main-in-other Z
2029 EOF
@@ -1973,6 +2031,7 @@ test_expect_success 'git checkout - with -B and --no-track, complete all referen
2031
2032 test_expect_success 'git switch - for -c, complete local branches and unique remote branches' '
2033 test_completion "git switch -c " <<-\EOF
2034 + HEAD Z
2035 branch-in-other Z
2036 main Z
2037 main-in-other Z
@@ -1982,6 +2041,7 @@ test_expect_success 'git switch - for -c, complete local branches and unique rem
2041
2042 test_expect_success 'git switch - for -C, complete local branches and unique remote branches' '
2043 test_completion "git switch -C " <<-\EOF
2044 + HEAD Z
2045 branch-in-other Z
2046 main Z
2047 main-in-other Z
@@ -2019,6 +2079,7 @@ test_expect_success 'git switch - for -C with --no-track, complete local branche
2079
2080 test_expect_success 'git checkout - for -b, complete local branches and unique remote branches' '
2081 test_completion "git checkout -b " <<-\EOF
2082 + HEAD Z
2083 branch-in-other Z
2084 main Z
2085 main-in-other Z
@@ -2028,6 +2089,7 @@ test_expect_success 'git checkout - for -b, complete local branches and unique r
2089
2090 test_expect_success 'git checkout - for -B, complete local branches and unique remote branches' '
2091 test_completion "git checkout -B " <<-\EOF
2092 + HEAD Z
2093 branch-in-other Z
2094 main Z
2095 main-in-other Z
@@ -2065,6 +2127,7 @@ test_expect_success 'git checkout - for -B with --no-track, complete local branc
2127
2128 test_expect_success 'git switch - with --orphan completes local branch names and unique remote branch names' '
2129 test_completion "git switch --orphan " <<-\EOF
2130 + HEAD Z
2131 branch-in-other Z
2132 main Z
2133 main-in-other Z
@@ -2080,6 +2143,7 @@ test_expect_success 'git switch - --orphan with branch already provided complete
2143
2144 test_expect_success 'git checkout - with --orphan completes local branch names and unique remote branch names' '
2145 test_completion "git checkout --orphan " <<-\EOF
2146 + HEAD Z
2147 branch-in-other Z
2148 main Z
2149 main-in-other Z
@@ -2093,6 +2157,7 @@ test_expect_success 'git checkout - --orphan with branch already provided comple
2157 main Z
2158 matching-branch Z
2159 matching-tag Z
2160 + other/HEAD Z
2161 other/branch-in-other Z
2162 other/main-in-other Z
2163 EOF