Skip to content

Commit

Permalink
completion: let 'for-each-ref' strip the remote name from remote bran…
Browse files Browse the repository at this point in the history
…ches

The code listing unique remote branches for 'git checkout's tracking
DWIMery uses a shell parameter expansion in a loop iterating over each
listed ref to remove the remote's name from the remote branches, i.e.
the leading path component from the short ref.  When listing refs from
a configured remote repository, '| sed s///' is used for the same
purpose.

Let 'git for-each-ref' strip one more leading path component from the
refs, i.e. use the format 'refname:strip=3' instead of '=2', making
that parameter expansion and 'sed' execution unnecessary.

This speeds up refs completion for 'git checkout'.  Uniquely
completing a branch for 'git checkout maste<TAB>' in a repo with 100k
remote branches, all packed, best of five:

  On Linux, near the beginning of this series, for reference:

    $ time __git_complete_refs --cur=maste --track

    real    0m8.185s
    user    0m6.896s
    sys     0m1.616s

  Before this patch:

    real    0m2.714s
    user    0m2.344s
    sys     0m0.436s

  After:

    real    0m1.993s
    user    0m1.740s
    sys     0m0.304s

  On Windows, near the beginning:

    real    1m8.421s
    user    0m7.591s
    sys     0m3.557s

  Before this patch:

    real    0m8.191s
    user    0m4.638s
    sys     0m2.918s

  After:

    real    0m6.187s
    user    0m3.358s
    sys     0m2.121s

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
szeder authored and gitster committed Mar 23, 2017
1 parent e896369 commit e8cb023
Showing 1 changed file with 3 additions and 4 deletions.
7 changes: 3 additions & 4 deletions contrib/completion/git-completion.bash
Expand Up @@ -423,11 +423,10 @@ __git_refs ()
# Try to find a remote branch that matches the completion word
# but only output if the branch name is unique
local ref entry
__git for-each-ref --shell --format="ref=%(refname:strip=2)" \
__git for-each-ref --shell --format="ref=%(refname:strip=3)" \
"refs/remotes/" | \
while read -r entry; do
eval "$entry"
ref="${ref#*/}"
if [[ "$ref" == "$match"* ]]; then
echo "$ref"
fi
Expand All @@ -450,9 +449,9 @@ __git_refs ()
case "HEAD" in
$match*) echo "HEAD" ;;
esac
__git for-each-ref --format="%(refname:strip=2)" \
__git for-each-ref --format="%(refname:strip=3)" \
"refs/remotes/$remote/$match*" \
"refs/remotes/$remote/$match*/**" | sed -e "s#^$remote/##"
"refs/remotes/$remote/$match*/**"
else
local query_symref
case "HEAD" in
Expand Down

0 comments on commit e8cb023

Please sign in to comment.