Skip to content

Commit 2ea328a

Browse files
szedergitster
authored andcommitted
completion: support completing full refs after '--option=refs/<TAB>'
Completing full refs currently only works when the full ref stands on in its own on the command line, but doesn't work when the current word to be completed contains a prefix before the full ref, e.g. '--option=refs/<TAB>' or 'master..refs/bis<TAB>'. The reason is that __git_refs() looks at the current word to be completed ($cur) as a whole to decide whether it has to list full (if it starts with 'refs/') or short refs (otherwise). However, $cur also holds said '--option=' or 'master..' prefixes, which of course throw off this decision. Luckily, the default action is to list short refs, that's why completing short refs happens to work even after a 'master..<TAB>' prefix and similar cases. Pass only the ref part of the current word to be completed to __git_refs() as a new positional parameter, so it can make the right decision even if the whole current word contains some kind of a prefix. Make this new parameter the 4. positional parameter and leave the 3. as an ignored placeholder for now (it will be used later in this patch series). Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 15b4a16 commit 2ea328a

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

contrib/completion/git-completion.bash

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -354,13 +354,16 @@ __git_tags ()
354354
# Can be the name of a configured remote, a path, or a URL.
355355
# 2: In addition to local refs, list unique branches from refs/remotes/ for
356356
# 'git checkout's tracking DWIMery (optional; ignored, if set but empty).
357+
# 3: Currently ignored.
358+
# 4: The current ref to be completed (optional).
357359
#
358360
# Use __git_complete_refs() instead.
359361
__git_refs ()
360362
{
361363
local i hash dir track="${2-}"
362364
local list_refs_from=path remote="${1-}"
363365
local format refs pfx
366+
local cur_="${4-$cur}"
364367

365368
__git_find_repo_path
366369
dir="$__git_repo_path"
@@ -384,14 +387,17 @@ __git_refs ()
384387
fi
385388

386389
if [ "$list_refs_from" = path ]; then
387-
case "$cur" in
390+
case "$cur_" in
388391
refs|refs/*)
389392
format="refname"
390-
refs="${cur%/*}"
393+
refs="${cur_%/*}"
391394
track=""
392395
;;
393396
*)
394-
[[ "$cur" == ^* ]] && pfx="^"
397+
if [[ "$cur_" == ^* ]]; then
398+
pfx="^"
399+
cur_=${cur_#^}
400+
fi
395401
for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
396402
if [ -e "$dir/$i" ]; then echo $pfx$i; fi
397403
done
@@ -411,16 +417,16 @@ __git_refs ()
411417
while read -r entry; do
412418
eval "$entry"
413419
ref="${ref#*/}"
414-
if [[ "$ref" == "$cur"* ]]; then
420+
if [[ "$ref" == "$cur_"* ]]; then
415421
echo "$ref"
416422
fi
417423
done | sort | uniq -u
418424
fi
419425
return
420426
fi
421-
case "$cur" in
427+
case "$cur_" in
422428
refs|refs/*)
423-
__git ls-remote "$remote" "$cur*" | \
429+
__git ls-remote "$remote" "$cur_*" | \
424430
while read -r hash i; do
425431
case "$i" in
426432
*^{}) ;;
@@ -475,7 +481,8 @@ __git_complete_refs ()
475481
shift
476482
done
477483

478-
__gitcomp_nl "$(__git_refs "$remote" "$track")" "$pfx" "$cur_" "$sfx"
484+
__gitcomp_nl "$(__git_refs "$remote" "$track" "" "$cur_")" \
485+
"$pfx" "$cur_" "$sfx"
479486
}
480487

481488
# __git_refs2 requires 1 argument (to pass to __git_refs)

t/t9902-completion.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,37 @@ test_expect_success '__git_refs - unique remote branches for git checkout DWIMer
775775
test_cmp expected "$actual"
776776
'
777777

778+
test_expect_success '__git_refs - after --opt=' '
779+
cat >expected <<-EOF &&
780+
HEAD
781+
master
782+
matching-branch
783+
other/branch-in-other
784+
other/master-in-other
785+
matching-tag
786+
EOF
787+
(
788+
cur="--opt=" &&
789+
__git_refs "" "" "" "" >"$actual"
790+
) &&
791+
test_cmp expected "$actual"
792+
'
793+
794+
test_expect_success '__git_refs - after --opt= - full refs' '
795+
cat >expected <<-EOF &&
796+
refs/heads/master
797+
refs/heads/matching-branch
798+
refs/remotes/other/branch-in-other
799+
refs/remotes/other/master-in-other
800+
refs/tags/matching-tag
801+
EOF
802+
(
803+
cur="--opt=refs/" &&
804+
__git_refs "" "" "" refs/ >"$actual"
805+
) &&
806+
test_cmp expected "$actual"
807+
'
808+
778809
test_expect_success '__git_complete_refs - simple' '
779810
sed -e "s/Z$//" >expected <<-EOF &&
780811
HEAD Z

0 commit comments

Comments
 (0)