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@xxxxxxxxx> --- contrib/completion/git-completion.bash | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 615292f8b..8f1203025 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -414,11 +414,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" == "$cur_"* ]]; then echo "$ref" fi @@ -439,9 +438,9 @@ __git_refs () *) if [ "$list_refs_from" = remote ]; then echo "HEAD" - __git for-each-ref --format="%(refname:strip=2)" \ + __git for-each-ref --format="%(refname:strip=3)" \ "refs/remotes/$remote/$cur_*" \ - "refs/remotes/$remote/$cur_*/**" | sed -e "s#^$remote/##" + "refs/remotes/$remote/$cur_*/**" else __git ls-remote "$remote" HEAD \ "refs/tags/$cur_*" "refs/heads/$cur_*" \ -- 2.11.0.555.g967c1bcb3