Skip to content

Commit

Permalink
completion: support completing full refs after '--option=refs/<TAB>'
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
szeder authored and gitster committed Mar 23, 2017
1 parent 15b4a16 commit 2ea328a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 7 deletions.
21 changes: 14 additions & 7 deletions contrib/completion/git-completion.bash
Original file line number Diff line number Diff line change
Expand Up @@ -354,13 +354,16 @@ __git_tags ()
# Can be the name of a configured remote, a path, or a URL.
# 2: In addition to local refs, list unique branches from refs/remotes/ for
# 'git checkout's tracking DWIMery (optional; ignored, if set but empty).
# 3: Currently ignored.
# 4: The current ref to be completed (optional).
#
# Use __git_complete_refs() instead.
__git_refs ()
{
local i hash dir track="${2-}"
local list_refs_from=path remote="${1-}"
local format refs pfx
local cur_="${4-$cur}"

__git_find_repo_path
dir="$__git_repo_path"
Expand All @@ -384,14 +387,17 @@ __git_refs ()
fi

if [ "$list_refs_from" = path ]; then
case "$cur" in
case "$cur_" in
refs|refs/*)
format="refname"
refs="${cur%/*}"
refs="${cur_%/*}"
track=""
;;
*)
[[ "$cur" == ^* ]] && pfx="^"
if [[ "$cur_" == ^* ]]; then
pfx="^"
cur_=${cur_#^}
fi
for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
if [ -e "$dir/$i" ]; then echo $pfx$i; fi
done
Expand All @@ -411,16 +417,16 @@ __git_refs ()
while read -r entry; do
eval "$entry"
ref="${ref#*/}"
if [[ "$ref" == "$cur"* ]]; then
if [[ "$ref" == "$cur_"* ]]; then
echo "$ref"
fi
done | sort | uniq -u
fi
return
fi
case "$cur" in
case "$cur_" in
refs|refs/*)
__git ls-remote "$remote" "$cur*" | \
__git ls-remote "$remote" "$cur_*" | \
while read -r hash i; do
case "$i" in
*^{}) ;;
Expand Down Expand Up @@ -475,7 +481,8 @@ __git_complete_refs ()
shift
done

__gitcomp_nl "$(__git_refs "$remote" "$track")" "$pfx" "$cur_" "$sfx"
__gitcomp_nl "$(__git_refs "$remote" "$track" "" "$cur_")" \
"$pfx" "$cur_" "$sfx"
}

# __git_refs2 requires 1 argument (to pass to __git_refs)
Expand Down
31 changes: 31 additions & 0 deletions t/t9902-completion.sh
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,37 @@ 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_complete_refs - simple' '
sed -e "s/Z$//" >expected <<-EOF &&
HEAD Z
Expand Down

0 comments on commit 2ea328a

Please sign in to comment.