From: Phillip Wood Date: Thu, 06 Mar 2025 16:35:26 GMT Subject: Re: [PATCH v2 2/2] completion: fix bugs with slashes in remote names Message-ID: <2bed28ca-b106-474d-9bac-db377bc51949@gmail.com> In-Reply-To: Hi David On 05/03/2025 20:50, David Mandelberg wrote: > David Mandelberg schreef op 2025-03-04 19:09: >> Previously, some calls to for-each-ref passed fixed numbers of path >> components to strip from refs, assuming that remote names had no slashes >> in them. This made completions like: >> >> git push github/dseomn :com >> >> Result in: >> >> git push github/dseomn :dseomn/completion-remote-slash >> >> With this patch, it instead results in: >> >> git push github/dseomn :completion-remote-slash >> >> Signed-off-by: David Mandelberg >> --- >> contrib/completion/git-completion.bash | 38 +++++- >> t/t9902-completion.sh | 180 ++++++++++++++++++++++--- >> 2 files changed, 189 insertions(+), 29 deletions(-) >> >> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash >> index 5fdc71208e..450fabc901 100644 >> --- a/contrib/completion/git-completion.bash >> +++ b/contrib/completion/git-completion.bash >> @@ -790,16 +790,39 @@ __git_tags () >> __git_dwim_remote_heads () >> { >> local pfx="${1-}" cur_="${2-}" sfx="${3-}" >> - local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers >> >> # employ the heuristic used by git checkout and git switch >> # Try to find a remote branch that cur_es the completion word >> # but only output if the branch name is unique >> - __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \ >> - --sort="refname:strip=3" \ >> - ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \ >> - "refs/remotes/*/$cur_*" "refs/remotes/*/$cur_*/**" | \ >> - uniq -u >> + local awk_script=' >> + function casemap(s) { >> + if (ENVIRON["IGNORE_CASE"]) >> + return tolower(s) >> + else >> + return s >> + } >> + BEGIN { >> + split(ENVIRON["REMOTES"], remotes, /\n/) >> + for (i in remotes) >> + remotes[i] = "refs/remotes/" casemap(remotes[i]) >> + cur_ = casemap(ENVIRON["CUR_"]) >> + } >> + { >> + ref_case = casemap($0) >> + for (i in remotes) { >> + if (index(ref_case, remotes[i] "/" cur_) == 1) { >> + branch = substr($0, length(remotes[i] "/") + 1) >> + print ENVIRON["PFX"] branch ENVIRON["SFX"] >> + break >> + } >> + } >> + } >> + ' >> + __git for-each-ref --format='%(refname)' | >> + PFX="$pfx" SFX="$sfx" CUR_="$cur_" \ >> + IGNORE_CASE=${GIT_COMPLETION_IGNORE_CASE+1} \ >> + REMOTES="$(__git_remotes | sort -r)" awk "$awk_script" | >> + sort | uniq -u I wonder if we can use "sort -u" here and drop uniq. It isn't quite the same as it will remove entries that are equal according to the current locale but I don't think that should matter. > I realized that this sends refs to awk that it doesn't need to. I'll > apply this diff to the next version of this patch: With that tweak this looks good. If there are no glob characters then "git for-each-ref" does a prefix match so strictly speaking you don't need the '**' but I don't think it matters in practice. I had one thought below but if you don't feel like spending more that on this I think what you have here is fine. The filtering is O(number of remote refs * number of remotes). If we could sort the list of remotes and remote refs in the same order then we can reduce this to O(number of remote refs + number of remotes) by doing (in pseudo code) for ($ref in $remote_refs) { while (!starts_with($ref, "refs/remotes/$remote[$i]")) $i++; if (starts_with($ref, "refs/remotes/$remote[$i]/$cur_) print $ref; } I think we can get "git for-each-ref --sort=-refname" and "sort -r" to agree on a sorting order by setting LC_COLLATE=C, otherwise "sort" will sort according the the current locale whereas git sorts by bytes. Best Wishes Phillip > diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash > index 450fabc901..c9d014070c 100644 > --- a/contrib/completion/git-completion.bash > +++ b/contrib/completion/git-completion.bash > @@ -818,7 +818,7 @@ __git_dwim_remote_heads () > } > } > ' > - __git for-each-ref --format='%(refname)' | > + __git for-each-ref --format='%(refname)' 'refs/remotes/**' | > PFX="$pfx" SFX="$sfx" CUR_="$cur_" \ > IGNORE_CASE=${GIT_COMPLETION_IGNORE_CASE+1} \ > REMOTES="$(__git_remotes | sort -r)" awk "$awk_script" | > >> } >> >> # Lists refs from the local (by default) or from a remote repository. >> @@ -905,7 +928,8 @@ __git_refs () >> case "HEAD" in >> $match*|$umatch*) echo "${pfx}HEAD$sfx" ;; >> esac >> - __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \ >> + local strip="$(__git_count_path_components "refs/remotes/$remote")" >> + __git for-each-ref --format="$fer_pfx%(refname:strip=$strip)$sfx" \ >> ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \ >> "refs/remotes/$remote/$match*" \ >> "refs/remotes/$remote/$match*/**" >> diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh >> index 015289c776..343b8cd191 100755 >> --- a/t/t9902-completion.sh >> +++ b/t/t9902-completion.sh >> @@ -149,7 +149,8 @@ fi >> test_expect_success 'setup for __git_find_repo_path/__gitdir tests' ' >> mkdir -p subdir/subsubdir && >> mkdir -p non-repo && >> - git init -b main otherrepo >> + git init -b main otherrepo && >> + git init -b main slashrepo >> ' >> >> test_expect_success '__git_find_repo_path - from command line (through $__git_dir)' ' >> @@ -674,6 +675,13 @@ test_expect_success 'setup for ref completion' ' >> ) && >> git remote add other "$ROOT/otherrepo/.git" && >> git fetch --no-tags other && >> + ( >> + cd slashrepo && >> + git commit --allow-empty -m initial && >> + git branch -m main branch/with/slash >> + ) && >> + git remote add remote/with/slash "$ROOT/slashrepo/.git" && >> + git fetch --no-tags remote/with/slash && >> rm -f .git/FETCH_HEAD && >> git init thirdrepo >> ' >> @@ -686,6 +694,8 @@ test_expect_success '__git_refs - simple' ' >> other/HEAD >> other/branch-in-other >> other/main-in-other >> + remote/with/slash/HEAD >> + remote/with/slash/branch/with/slash >> matching-tag >> EOF >> ( >> @@ -702,6 +712,8 @@ test_expect_success '__git_refs - full refs' ' >> refs/remotes/other/HEAD >> refs/remotes/other/branch-in-other >> refs/remotes/other/main-in-other >> + refs/remotes/remote/with/slash/HEAD >> + refs/remotes/remote/with/slash/branch/with/slash >> refs/tags/matching-tag >> EOF >> ( >> @@ -767,6 +779,19 @@ test_expect_success '__git_refs - configured remote' ' >> test_cmp expected "$actual" >> ' >> >> +test_expect_success '__git_refs - configured remote - with slash' ' >> + cat >expected <<-EOF && >> + HEAD >> + HEAD >> + branch/with/slash >> + EOF >> + ( >> + cur= && >> + __git_refs remote/with/slash >"$actual" >> + ) && >> + test_cmp expected "$actual" >> +' >> + >> test_expect_success '__git_refs - configured remote - full refs' ' >> cat >expected <<-EOF && >> HEAD >> @@ -909,17 +934,19 @@ test_expect_success '__git_refs - unique remote branches for git checkout DWIMer >> other/ambiguous >> other/branch-in-other >> other/main-in-other >> - remote/ambiguous >> - remote/branch-in-remote >> + remote/with/slash/HEAD >> + remote/with/slash/ambiguous >> + remote/with/slash/branch-in-remote >> + remote/with/slash/branch/with/slash >> matching-tag >> - HEAD >> branch-in-other >> branch-in-remote >> + branch/with/slash >> main-in-other >> EOF >> for remote_ref in refs/remotes/other/ambiguous \ >> - refs/remotes/remote/ambiguous \ >> - refs/remotes/remote/branch-in-remote >> + refs/remotes/remote/with/slash/ambiguous \ >> + refs/remotes/remote/with/slash/branch-in-remote >> do >> git update-ref $remote_ref main && >> test_when_finished "git update-ref -d $remote_ref" || return 1 >> @@ -939,6 +966,8 @@ test_expect_success '__git_refs - after --opt=' ' >> other/HEAD >> other/branch-in-other >> other/main-in-other >> + remote/with/slash/HEAD >> + remote/with/slash/branch/with/slash >> matching-tag >> EOF >> ( >> @@ -955,6 +984,8 @@ test_expect_success '__git_refs - after --opt= - full refs' ' >> refs/remotes/other/HEAD >> refs/remotes/other/branch-in-other >> refs/remotes/other/main-in-other >> + refs/remotes/remote/with/slash/HEAD >> + refs/remotes/remote/with/slash/branch/with/slash >> refs/tags/matching-tag >> EOF >> ( >> @@ -972,6 +1003,8 @@ test_expect_success '__git refs - excluding refs' ' >> ^other/HEAD >> ^other/branch-in-other >> ^other/main-in-other >> + ^remote/with/slash/HEAD >> + ^remote/with/slash/branch/with/slash >> ^matching-tag >> EOF >> ( >> @@ -988,6 +1021,8 @@ test_expect_success '__git refs - excluding full refs' ' >> ^refs/remotes/other/HEAD >> ^refs/remotes/other/branch-in-other >> ^refs/remotes/other/main-in-other >> + ^refs/remotes/remote/with/slash/HEAD >> + ^refs/remotes/remote/with/slash/branch/with/slash >> ^refs/tags/matching-tag >> EOF >> ( >> @@ -1015,6 +1050,8 @@ test_expect_success '__git_refs - do not filter refs unless told so' ' >> other/branch-in-other >> other/main-in-other >> other/matching/branch-in-other >> + remote/with/slash/HEAD >> + remote/with/slash/branch/with/slash >> matching-tag >> matching/tag >> EOF >> @@ -1135,6 +1172,8 @@ test_expect_success '__git_complete_refs - simple' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> matching-tag Z >> EOF >> ( >> @@ -1173,6 +1212,20 @@ test_expect_success '__git_complete_refs - remote' ' >> test_cmp expected out >> ' >> >> +test_expect_success '__git_complete_refs - remote - with slash' ' >> + sed -e "s/Z$//" >expected <<-EOF && >> + HEAD Z >> + HEAD Z >> + branch/with/slash Z >> + EOF >> + ( >> + cur= && >> + __git_complete_refs --remote=remote/with/slash && >> + print_comp >> + ) && >> + test_cmp expected out >> +' >> + >> test_expect_success '__git_complete_refs - track' ' >> sed -e "s/Z$//" >expected <<-EOF && >> HEAD Z >> @@ -1181,9 +1234,11 @@ test_expect_success '__git_complete_refs - track' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> matching-tag Z >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main-in-other Z >> EOF >> ( >> @@ -1228,6 +1283,8 @@ test_expect_success '__git_complete_refs - suffix' ' >> other/HEAD. >> other/branch-in-other. >> other/main-in-other. >> + remote/with/slash/HEAD. >> + remote/with/slash/branch/with/slash. >> matching-tag. >> EOF >> ( >> @@ -1253,6 +1310,20 @@ test_expect_success '__git_complete_fetch_refspecs - simple' ' >> test_cmp expected out >> ' >> >> +test_expect_success '__git_complete_fetch_refspecs - with slash' ' >> + sed -e "s/Z$//" >expected <<-EOF && >> + HEAD:HEAD Z >> + HEAD:HEAD Z >> + branch/with/slash:branch/with/slash Z >> + EOF >> + ( >> + cur= && >> + __git_complete_fetch_refspecs remote/with/slash && >> + print_comp >> + ) && >> + test_cmp expected out >> +' >> + >> test_expect_success '__git_complete_fetch_refspecs - matching' ' >> sed -e "s/Z$//" >expected <<-EOF && >> branch-in-other:branch-in-other Z >> @@ -1333,8 +1404,8 @@ test_expect_success '__git_complete_worktree_paths with -C' ' >> >> test_expect_success 'git switch - with no options, complete local branches and unique remote branch names for DWIM logic' ' >> test_completion "git switch " <<-\EOF >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -1480,8 +1551,8 @@ test_expect_success 'git-bisect - existing view subcommand is recognized and ena >> test_expect_success 'git checkout - completes refs and unique remote branches for DWIM' ' >> test_completion "git checkout " <<-\EOF >> HEAD Z >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -1489,6 +1560,8 @@ test_expect_success 'git checkout - completes refs and unique remote branches fo >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1508,8 +1581,8 @@ test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, compl >> >> test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' ' >> GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch --guess " <<-\EOF >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -1518,8 +1591,8 @@ test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_G >> >> test_expect_success 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' ' >> test_completion "git switch --no-guess --guess " <<-\EOF >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -1542,14 +1615,16 @@ test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only complete >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> test_expect_success 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, complete refs and unique remote branches for DWIM' ' >> GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout --guess " <<-\EOF >> HEAD Z >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -1557,6 +1632,8 @@ test_expect_success 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1569,14 +1646,16 @@ test_expect_success 'git checkout - with --no-guess, only completes refs' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> test_expect_success 'git checkout - a later --guess overrides previous --no-guess, complete refs and unique remote branches for DWIM' ' >> test_completion "git checkout --no-guess --guess " <<-\EOF >> HEAD Z >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -1584,6 +1663,8 @@ test_expect_success 'git checkout - a later --guess overrides previous --no-gues >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1596,6 +1677,8 @@ test_expect_success 'git checkout - a later --no-guess overrides previous --gues >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1609,6 +1692,8 @@ test_expect_success 'git checkout - with checkout.guess = false, only completes >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1616,8 +1701,8 @@ test_expect_success 'git checkout - with checkout.guess = true, completes refs a >> test_config checkout.guess true && >> test_completion "git checkout " <<-\EOF >> HEAD Z >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -1625,6 +1710,8 @@ test_expect_success 'git checkout - with checkout.guess = true, completes refs a >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1632,8 +1719,8 @@ test_expect_success 'git checkout - a later --guess overrides previous checkout. >> test_config checkout.guess false && >> test_completion "git checkout --guess " <<-\EOF >> HEAD Z >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -1641,6 +1728,8 @@ test_expect_success 'git checkout - a later --guess overrides previous checkout. >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1654,6 +1743,8 @@ test_expect_success 'git checkout - a later --no-guess overrides previous checko >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1666,6 +1757,8 @@ test_expect_success 'git switch - with --detach, complete all references' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1678,6 +1771,8 @@ test_expect_success 'git checkout - with --detach, complete only references' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1850,6 +1945,8 @@ test_expect_success 'git switch - with -d, complete all references' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1862,6 +1959,8 @@ test_expect_success 'git checkout - with -d, complete only references' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1870,11 +1969,15 @@ test_expect_success 'git switch - with --track, complete only remote branches' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> test_completion "git switch -t " <<-\EOF >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1883,11 +1986,15 @@ test_expect_success 'git checkout - with --track, complete only remote branches' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> test_completion "git checkout -t " <<-\EOF >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1907,6 +2014,8 @@ test_expect_success 'git checkout - with --no-track, complete only local referen >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1919,6 +2028,8 @@ test_expect_success 'git switch - with -c, complete all references' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1931,6 +2042,8 @@ test_expect_success 'git switch - with -C, complete all references' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1943,6 +2056,8 @@ test_expect_success 'git switch - with -c and --track, complete all references' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1955,6 +2070,8 @@ test_expect_success 'git switch - with -C and --track, complete all references' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1967,6 +2084,8 @@ test_expect_success 'git switch - with -c and --no-track, complete all reference >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1979,6 +2098,8 @@ test_expect_success 'git switch - with -C and --no-track, complete all reference >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -1991,6 +2112,8 @@ test_expect_success 'git checkout - with -b, complete all references' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -2003,6 +2126,8 @@ test_expect_success 'git checkout - with -B, complete all references' ' >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -2015,6 +2140,8 @@ test_expect_success 'git checkout - with -b and --track, complete all references >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -2027,6 +2154,8 @@ test_expect_success 'git checkout - with -B and --track, complete all references >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -2039,6 +2168,8 @@ test_expect_success 'git checkout - with -b and --no-track, complete all referen >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -2051,13 +2182,15 @@ test_expect_success 'git checkout - with -B and --no-track, complete all referen >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> test_expect_success 'git switch - for -c, complete local branches and unique remote branches' ' >> test_completion "git switch -c " <<-\EOF >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -2066,8 +2199,8 @@ test_expect_success 'git switch - for -c, complete local branches and unique rem >> >> test_expect_success 'git switch - for -C, complete local branches and unique remote branches' ' >> test_completion "git switch -C " <<-\EOF >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -2104,8 +2237,8 @@ test_expect_success 'git switch - for -C with --no-track, complete local branche >> >> test_expect_success 'git checkout - for -b, complete local branches and unique remote branches' ' >> test_completion "git checkout -b " <<-\EOF >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -2114,8 +2247,8 @@ test_expect_success 'git checkout - for -b, complete local branches and unique r >> >> test_expect_success 'git checkout - for -B, complete local branches and unique remote branches' ' >> test_completion "git checkout -B " <<-\EOF >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -2152,8 +2285,8 @@ test_expect_success 'git checkout - for -B with --no-track, complete local branc >> >> test_expect_success 'git switch - with --orphan completes local branch names and unique remote branch names' ' >> test_completion "git switch --orphan " <<-\EOF >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -2168,8 +2301,8 @@ test_expect_success 'git switch - --orphan with branch already provided complete >> >> test_expect_success 'git checkout - with --orphan completes local branch names and unique remote branch names' ' >> test_completion "git checkout --orphan " <<-\EOF >> - HEAD Z >> branch-in-other Z >> + branch/with/slash Z >> main Z >> main-in-other Z >> matching-branch Z >> @@ -2185,6 +2318,8 @@ test_expect_success 'git checkout - --orphan with branch already provided comple >> other/HEAD Z >> other/branch-in-other Z >> other/main-in-other Z >> + remote/with/slash/HEAD Z >> + remote/with/slash/branch/with/slash Z >> EOF >> ' >> >> @@ -2199,7 +2334,8 @@ test_expect_success 'git restore completes modified files' ' >> test_expect_success 'teardown after ref completion' ' >> git branch -d matching-branch && >> git tag -d matching-tag && >> - git remote remove other >> + git remote remove other && >> + git remote remove remote/with/slash >> ' >