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....@gmail.com>
---
 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 976f80598..206eaf0ca 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -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
@@ -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
-- 
2.12.1.485.g1616aa492

Reply via email to