From 2ea328a119709a2a94b16cea28ef0e5d7405c5f9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?SZEDER=20G=C3=A1bor?= Date: Thu, 23 Mar 2017 16:29:13 +0100 Subject: [PATCH] completion: support completing full refs after '--option=refs/' MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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/' or 'master..refs/bis'. 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..' 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 Signed-off-by: Junio C Hamano --- contrib/completion/git-completion.bash | 21 ++++++++++++++------- t/t9902-completion.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 0b90cfa54..b897cba4b 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -354,6 +354,8 @@ __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 () @@ -361,6 +363,7 @@ __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" @@ -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 @@ -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 *^{}) ;; @@ -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) diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 4e7f3076f..0a41ee1ea 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -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 -- 2.11.0