Skip to content

Commit 778d2f1

Browse files
dseomngitster
authored andcommitted
completion: fix bugs with slashes in remote names
Previously, some calls to for-each-ref passed fixed numbers of path components to strip from refs, assuming that remote names had no slashes in them. This made completions like: git push github/dseomn :com<Tab> Result in: git push github/dseomn :dseomn/completion-remote-slash With this patch, it instead results in: git push github/dseomn :completion-remote-slash Signed-off-by: David Mandelberg <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5637bdc commit 778d2f1

File tree

2 files changed

+189
-29
lines changed

2 files changed

+189
-29
lines changed

contrib/completion/git-completion.bash

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -790,16 +790,39 @@ __git_tags ()
790790
__git_dwim_remote_heads ()
791791
{
792792
local pfx="${1-}" cur_="${2-}" sfx="${3-}"
793-
local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
794793

795794
# employ the heuristic used by git checkout and git switch
796795
# Try to find a remote branch that cur_es the completion word
797796
# but only output if the branch name is unique
798-
__git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
799-
--sort="refname:strip=3" \
800-
${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
801-
"refs/remotes/*/$cur_*" "refs/remotes/*/$cur_*/**" | \
802-
uniq -u
797+
local awk_script='
798+
function casemap(s) {
799+
if (ENVIRON["IGNORE_CASE"])
800+
return tolower(s)
801+
else
802+
return s
803+
}
804+
BEGIN {
805+
split(ENVIRON["REMOTES"], remotes, /\n/)
806+
for (i in remotes)
807+
remotes[i] = "refs/remotes/" casemap(remotes[i])
808+
cur_ = casemap(ENVIRON["CUR_"])
809+
}
810+
{
811+
ref_case = casemap($0)
812+
for (i in remotes) {
813+
if (index(ref_case, remotes[i] "/" cur_) == 1) {
814+
branch = substr($0, length(remotes[i] "/") + 1)
815+
print ENVIRON["PFX"] branch ENVIRON["SFX"]
816+
break
817+
}
818+
}
819+
}
820+
'
821+
__git for-each-ref --format='%(refname)' refs/remotes/ |
822+
PFX="$pfx" SFX="$sfx" CUR_="$cur_" \
823+
IGNORE_CASE=${GIT_COMPLETION_IGNORE_CASE+1} \
824+
REMOTES="$(__git_remotes | sort -r)" awk "$awk_script" |
825+
sort | uniq -u
803826
}
804827

805828
# Lists refs from the local (by default) or from a remote repository.
@@ -905,7 +928,8 @@ __git_refs ()
905928
case "HEAD" in
906929
$match*|$umatch*) echo "${pfx}HEAD$sfx" ;;
907930
esac
908-
__git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
931+
local strip="$(__git_count_path_components "refs/remotes/$remote")"
932+
__git for-each-ref --format="$fer_pfx%(refname:strip=$strip)$sfx" \
909933
${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
910934
"refs/remotes/$remote/$match*" \
911935
"refs/remotes/$remote/$match*/**"

0 commit comments

Comments
 (0)