The code listing unique remote branches for 'git checkout's tracking
DWIMery outputs only remote branches that match the current word to be
completed, but the filtering is done in a shell loop iterating over
all remote refs.

Let 'git for-each-ref' do the filtering, as it can do so much more
efficiently and we can remove that shell loop entirely.

This speeds up refs completion for 'git checkout' considerably when
there are a lot of non-matching remote refs to be filtered out.
Uniquely completing a branch in a repository with 100k remote
branches, all packed, best of five:

  On Linux, before:

    $ time __git_complete_refs --cur=maste --track

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

  After:

    real    0m0.266s
    user    0m0.248s
    sys     0m0.012s

  On Windows, before:

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

  After:

    real    0m0.750s
    user    0m0.015s
    sys     0m0.090s

Signed-off-by: SZEDER Gábor <szeder....@gmail.com>
---
 contrib/completion/git-completion.bash | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index 8f1203025..e2c4794f3 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -413,15 +413,9 @@ __git_refs ()
                        # employ the heuristic used by git checkout
                        # 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=3)" \
-                               "refs/remotes/" | \
-                       while read -r entry; do
-                               eval "$entry"
-                               if [[ "$ref" == "$cur_"* ]]; then
-                                       echo "$ref"
-                               fi
-                       done | sort | uniq -u
+                       __git for-each-ref --format="%(refname:strip=3)" \
+                               "refs/remotes/*/$cur_*" 
"refs/remotes/*/$cur_*/**" | \
+                       sort | uniq -u
                fi
                return
        fi
-- 
2.11.0.555.g967c1bcb3

Reply via email to