git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 2/2] completion: fix bugs with slashes in remote names

From
PWPhillip Wood <phillip.wood123@gmail.com>
Date
Mar 6, 2025, 17:39 UTC
Message-ID
<b87cd755-b297-47ef-a1ad-8e06091333b8@gmail.com>
In-Reply-To
<7f00dc07-5905-4571-84f4-e50c39867818@mandelberg.org>
Hi David
On 06/03/2025 17:12, David Mandelberg wrote:
Show 20 quoted lines
> Op 2025-03-06 om 11:35 schreef Phillip Wood:
>
>>>> +    __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.
> 
> That's what I thought when I first saw that, but `uniq -u` removes 
> duplicates:
> 
> $ printf 'a\nb\na\n' | sort | uniq -u
> b
> $ printf 'a\nb\na\n' | sort -u
> a
> b
Oh, thanks for pointing that out
Show 34 quoted lines
>   >> 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.
> 
> On my desktop, a similar-ish loop takes about 0.1s with 1000*1000 
> iterations. 1000 remote branches seems plausible but on the high side to 
> me, and 1000 remotes seems very high to me. Do you still think it's 
> worth optimizing? I do think your solution would work, but I think it 
> would take a decent amount of testing to avoid the collation issues you 
> mentioned, and off-by-one errors and the like. So I'd rather not do it 
> unless there's a practical performance advantage, not just theoretical. 
> (Which is what I thought about minimizing forks too, before I learned 
> that it was a practical issue.)

Thanks for running a benchmark. I'm fine with leaving it as is, it is definitely simpler and easier to understand. We can always revisit the filtering in the future if it turns out to be a too slow for some reason.

Best Wishes
Phillip
Show 714 quoted lines
> $ time seq 1 1000 | LONG="$(seq 1 1000)" awk 'BEGIN 
> { split(ENVIRON["LONG"], long, /\n/); } { for (i in long) { if ($0 == 
> long[i]) { print; }  } }' > /dev/null
> 
> real    0m0,092s
> user    0m0,067s
> sys     0m0,028s
> 
>> 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
>>>>   '
>>>
>>
> 
Previous: David MandelbergNext: David Mandelberg
Message 31 of 44 in “completion: fix bugs with slashes in remote names”
  1. 0/3 completion: fix bugs with slashes in remote namesDavid Mandelberg via GitGitGadget, Mar 2, 2025
  2. 1/3 completion: add helper to escape strings for fnmatchDavid Mandelberg via GitGitGadget, Mar 2, 2025
  3. 2/3 completion: add helper to count path componentsDavid Mandelberg via GitGitGadget, Mar 2, 2025
  4. 3/3 completion: fix bugs with slashes in remote namesDavid Mandelberg via GitGitGadget, Mar 2, 2025
  5. Phillip WoodMar 2, 2025
  6. David MandelbergMar 2, 2025
  7. phillip.wood123@gmail.comMar 3, 2025
  8. David MandelbergMar 3, 2025
  9. Todd ZullingerMar 3, 2025
  10. D. Ben KnobleMar 6, 2025
  11. D. Ben KnobleMar 6, 2025
  12. Junio C HamanoMar 6, 2025
  13. phillip.wood123@gmail.comMar 7, 2025
  14. David MandelbergMar 7, 2025
  15. D. Ben KnobleMar 13, 2025
  16. David MandelbergMar 13, 2025
  17. Junio C HamanoMar 3, 2025
  18. SZEDER GáborMar 3, 2025
  19. David MandelbergMar 3, 2025
  20. Junio C HamanoMar 6, 2025
  21. David MandelbergMar 7, 2025
  22. Junio C HamanoMar 7, 2025
  23. David MandelbergMar 7, 2025
  24. Junio C HamanoMar 7, 2025
  25. 0/2 completion: fix bugs with slashes in remote namesDavid Mandelberg, Mar 5, 2025
  26. 1/2 completion: add helper to count path componentsDavid Mandelberg, Mar 5, 2025
  27. 2/2 completion: fix bugs with slashes in remote namesDavid Mandelberg, Mar 5, 2025
  28. David MandelbergMar 5, 2025
  29. Phillip WoodMar 6, 2025
  30. David MandelbergMar 6, 2025
  31. Phillip WoodMar 6, 2025
  32. 0/2 completion: fix bugs with slashes in remote namesDavid Mandelberg, Mar 14, 2025
  33. 1/2 completion: add helper to count path componentsDavid Mandelberg, Mar 14, 2025
  34. 2/2 completion: fix bugs with slashes in remote namesDavid Mandelberg, Mar 14, 2025
  35. Junio C HamanoMar 14, 2025
  36. David MandelbergMar 14, 2025
  37. Junio C HamanoMar 14, 2025
  38. Phillip WoodMar 18, 2025
  39. Junio C HamanoMar 18, 2025
  40. 0/2 completion: fix bugs with slashes in remote namesDavid Mandelberg, Mar 23, 2025
  41. 1/2 completion: add helper to count path componentsDavid Mandelberg, Mar 23, 2025
  42. 2/2 completion: fix bugs with slashes in remote namesDavid Mandelberg, Mar 23, 2025
  43. Phillip WoodApr 8, 2025
  44. David MandelbergApr 8, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.