completion: let 'for-each-ref' sort remote branches for 'checkout' DWIMery

When listing unique remote branches for 'git checkout's tracking
DWIMery, __git_refs() runs the classic '... |sort |uniq -u' pattern to
filter out duplicate remote branches.

Let 'git for-each-ref' do the sorting, sparing the overhead of
fork()+exec()ing 'sort' and a stage in the pipeline where potentially
relatively large amount of data can be passed between two subsequent
pipeline stages.

This speeds up refs completion for 'git checkout' a bit when a lot of
remote branches match the current word to be completed.  Listing a
single local and 100k remote branches, all packed, best of five:

  On Linux, before:

    $ time __git_complete_refs --track

    real    0m1.856s
    user    0m1.816s
    sys     0m0.060s

  After:

    real    0m1.550s
    user    0m1.512s
    sys     0m0.060s

  On Windows, before:

    real    0m3.128s
    user    0m2.155s
    sys     0m0.183s

  After:

    real    0m2.781s
    user    0m1.826s
    sys     0m0.136s

Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
SZEDER Gábor 2017-03-23 16:29:21 +01:00 committed by Junio C Hamano
parent 824388d54b
commit 400a7553c4

View file

@ -423,8 +423,9 @@ __git_refs ()
# Try to find a remote branch that matches the completion word
# but only output if the branch name is unique
__git for-each-ref --format="%(refname:strip=3)" \
--sort="refname:strip=3" \
"refs/remotes/*/$match*" "refs/remotes/*/$match*/**" | \
sort | uniq -u
uniq -u
fi
return
fi