Merge branch 'sg/completion-refs-speedup'

The refs completion for large number of refs has been sped up,
partly by giving up disambiguating ambiguous refs and partly by
eliminating most of the shell processing between 'git for-each-ref'
and 'ls-remote' and Bash's completion facility.

* sg/completion-refs-speedup:
  completion: speed up branch and tag completion
  completion: fill COMPREPLY directly when completing fetch refspecs
  completion: fill COMPREPLY directly when completing refs
  completion: let 'for-each-ref' sort remote branches for 'checkout' DWIMery
  completion: let 'for-each-ref' filter remote branches for 'checkout' DWIMery
  completion: let 'for-each-ref' strip the remote name from remote branches
  completion: let 'for-each-ref' and 'ls-remote' filter matching refs
  completion: don't disambiguate short refs
  completion: don't disambiguate tags and branches
  completion: support excluding full refs
  completion: support completing fully qualified non-fast-forward refspecs
  completion: support completing full refs after '--option=refs/<TAB>'
  completion: wrap __git_refs() for better option parsing
  completion: remove redundant __gitcomp_nl() options from _git_commit()
This commit is contained in:
Junio C Hamano
2017-03-30 14:07:14 -07:00
3 changed files with 577 additions and 71 deletions

View File

@ -400,6 +400,22 @@ test_expect_success '__gitdir - remote as argument' '
test_cmp expected "$actual"
'
test_expect_success '__gitcomp_direct - puts everything into COMPREPLY as-is' '
sed -e "s/Z$//g" >expected <<-EOF &&
with-trailing-space Z
without-trailing-spaceZ
--option Z
--option=Z
$invalid_variable_name Z
EOF
(
cur=should_be_ignored &&
__gitcomp_direct "$(cat expected)" &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__gitcomp - trailing space - options' '
test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
--reset-author" <<-EOF
@ -555,6 +571,9 @@ test_expect_success '__git_refs - full refs' '
cat >expected <<-EOF &&
refs/heads/master
refs/heads/matching-branch
refs/remotes/other/branch-in-other
refs/remotes/other/master-in-other
refs/tags/matching-tag
EOF
(
cur=refs/heads/ &&
@ -620,6 +639,7 @@ test_expect_success '__git_refs - configured remote' '
test_expect_success '__git_refs - configured remote - full refs' '
cat >expected <<-EOF &&
HEAD
refs/heads/branch-in-other
refs/heads/master-in-other
refs/tags/tag-in-other
@ -648,6 +668,7 @@ test_expect_success '__git_refs - configured remote - repo given on the command
test_expect_success '__git_refs - configured remote - full refs - repo given on the command line' '
cat >expected <<-EOF &&
HEAD
refs/heads/branch-in-other
refs/heads/master-in-other
refs/tags/tag-in-other
@ -692,6 +713,7 @@ test_expect_success '__git_refs - URL remote' '
test_expect_success '__git_refs - URL remote - full refs' '
cat >expected <<-EOF &&
HEAD
refs/heads/branch-in-other
refs/heads/master-in-other
refs/tags/tag-in-other
@ -775,6 +797,371 @@ test_expect_success '__git_refs - unique remote branches for git checkout DWIMer
test_cmp expected "$actual"
'
test_expect_success '__git_refs - after --opt=' '
cat >expected <<-EOF &&
HEAD
master
matching-branch
other/branch-in-other
other/master-in-other
matching-tag
EOF
(
cur="--opt=" &&
__git_refs "" "" "" "" >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success '__git_refs - after --opt= - full refs' '
cat >expected <<-EOF &&
refs/heads/master
refs/heads/matching-branch
refs/remotes/other/branch-in-other
refs/remotes/other/master-in-other
refs/tags/matching-tag
EOF
(
cur="--opt=refs/" &&
__git_refs "" "" "" refs/ >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success '__git refs - exluding refs' '
cat >expected <<-EOF &&
^HEAD
^master
^matching-branch
^other/branch-in-other
^other/master-in-other
^matching-tag
EOF
(
cur=^ &&
__git_refs >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success '__git refs - exluding full refs' '
cat >expected <<-EOF &&
^refs/heads/master
^refs/heads/matching-branch
^refs/remotes/other/branch-in-other
^refs/remotes/other/master-in-other
^refs/tags/matching-tag
EOF
(
cur=^refs/ &&
__git_refs >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success 'setup for filtering matching refs' '
git branch matching/branch &&
git tag matching/tag &&
git -C otherrepo branch matching/branch-in-other &&
git fetch --no-tags other &&
rm -f .git/FETCH_HEAD
'
test_expect_success '__git_refs - dont filter refs unless told so' '
cat >expected <<-EOF &&
HEAD
master
matching-branch
matching/branch
other/branch-in-other
other/master-in-other
other/matching/branch-in-other
matching-tag
matching/tag
EOF
(
cur=master &&
__git_refs >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success '__git_refs - only matching refs' '
cat >expected <<-EOF &&
matching-branch
matching/branch
matching-tag
matching/tag
EOF
(
cur=mat &&
__git_refs "" "" "" "$cur" >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success '__git_refs - only matching refs - full refs' '
cat >expected <<-EOF &&
refs/heads/matching-branch
refs/heads/matching/branch
EOF
(
cur=refs/heads/mat &&
__git_refs "" "" "" "$cur" >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success '__git_refs - only matching refs - remote on local file system' '
cat >expected <<-EOF &&
master-in-other
matching/branch-in-other
EOF
(
cur=ma &&
__git_refs otherrepo "" "" "$cur" >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success '__git_refs - only matching refs - configured remote' '
cat >expected <<-EOF &&
master-in-other
matching/branch-in-other
EOF
(
cur=ma &&
__git_refs other "" "" "$cur" >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success '__git_refs - only matching refs - remote - full refs' '
cat >expected <<-EOF &&
refs/heads/master-in-other
refs/heads/matching/branch-in-other
EOF
(
cur=refs/heads/ma &&
__git_refs other "" "" "$cur" >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success '__git_refs - only matching refs - checkout DWIMery' '
cat >expected <<-EOF &&
matching-branch
matching/branch
matching-tag
matching/tag
matching/branch-in-other
EOF
for remote_ref in refs/remotes/other/ambiguous \
refs/remotes/remote/ambiguous \
refs/remotes/remote/branch-in-remote
do
git update-ref $remote_ref master &&
test_when_finished "git update-ref -d $remote_ref"
done &&
(
cur=mat &&
__git_refs "" 1 "" "$cur" >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success 'teardown after filtering matching refs' '
git branch -d matching/branch &&
git tag -d matching/tag &&
git update-ref -d refs/remotes/other/matching/branch-in-other &&
git -C otherrepo branch -D matching/branch-in-other
'
test_expect_success '__git_refs - for-each-ref format specifiers in prefix' '
cat >expected <<-EOF &&
evil-%%-%42-%(refname)..master
EOF
(
cur="evil-%%-%42-%(refname)..mas" &&
__git_refs "" "" "evil-%%-%42-%(refname).." mas >"$actual"
) &&
test_cmp expected "$actual"
'
test_expect_success '__git_complete_refs - simple' '
sed -e "s/Z$//" >expected <<-EOF &&
HEAD Z
master Z
matching-branch Z
other/branch-in-other Z
other/master-in-other Z
matching-tag Z
EOF
(
cur= &&
__git_complete_refs &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__git_complete_refs - matching' '
sed -e "s/Z$//" >expected <<-EOF &&
matching-branch Z
matching-tag Z
EOF
(
cur=mat &&
__git_complete_refs &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__git_complete_refs - remote' '
sed -e "s/Z$//" >expected <<-EOF &&
HEAD Z
branch-in-other Z
master-in-other Z
EOF
(
cur=
__git_complete_refs --remote=other &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__git_complete_refs - track' '
sed -e "s/Z$//" >expected <<-EOF &&
HEAD Z
master Z
matching-branch Z
other/branch-in-other Z
other/master-in-other Z
matching-tag Z
branch-in-other Z
master-in-other Z
EOF
(
cur=
__git_complete_refs --track &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__git_complete_refs - current word' '
sed -e "s/Z$//" >expected <<-EOF &&
matching-branch Z
matching-tag Z
EOF
(
cur="--option=mat" &&
__git_complete_refs --cur="${cur#*=}" &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__git_complete_refs - prefix' '
sed -e "s/Z$//" >expected <<-EOF &&
v1.0..matching-branch Z
v1.0..matching-tag Z
EOF
(
cur=v1.0..mat &&
__git_complete_refs --pfx=v1.0.. --cur=mat &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__git_complete_refs - suffix' '
cat >expected <<-EOF &&
HEAD.
master.
matching-branch.
other/branch-in-other.
other/master-in-other.
matching-tag.
EOF
(
cur= &&
__git_complete_refs --sfx=. &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__git_complete_fetch_refspecs - simple' '
sed -e "s/Z$//" >expected <<-EOF &&
HEAD:HEAD Z
branch-in-other:branch-in-other Z
master-in-other:master-in-other Z
EOF
(
cur= &&
__git_complete_fetch_refspecs other &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__git_complete_fetch_refspecs - matching' '
sed -e "s/Z$//" >expected <<-EOF &&
branch-in-other:branch-in-other Z
EOF
(
cur=br &&
__git_complete_fetch_refspecs other "" br &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__git_complete_fetch_refspecs - prefix' '
sed -e "s/Z$//" >expected <<-EOF &&
+HEAD:HEAD Z
+branch-in-other:branch-in-other Z
+master-in-other:master-in-other Z
EOF
(
cur="+" &&
__git_complete_fetch_refspecs other "+" "" &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__git_complete_fetch_refspecs - fully qualified' '
sed -e "s/Z$//" >expected <<-EOF &&
refs/heads/branch-in-other:refs/heads/branch-in-other Z
refs/heads/master-in-other:refs/heads/master-in-other Z
refs/tags/tag-in-other:refs/tags/tag-in-other Z
EOF
(
cur=refs/ &&
__git_complete_fetch_refspecs other "" refs/ &&
print_comp
) &&
test_cmp expected out
'
test_expect_success '__git_complete_fetch_refspecs - fully qualified & prefix' '
sed -e "s/Z$//" >expected <<-EOF &&
+refs/heads/branch-in-other:refs/heads/branch-in-other Z
+refs/heads/master-in-other:refs/heads/master-in-other Z
+refs/tags/tag-in-other:refs/tags/tag-in-other Z
EOF
(
cur=+refs/ &&
__git_complete_fetch_refspecs other + refs/ &&
print_comp
) &&
test_cmp expected out
'
test_expect_success 'teardown after ref completion' '
git branch -d matching-branch &&
git tag -d matching-tag &&