aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/completion/git-completion.bash
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/completion/git-completion.bash')
-rw-r--r--contrib/completion/git-completion.bash49
1 files changed, 42 insertions, 7 deletions
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 413911be3b..e3d88b0672 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -234,6 +234,17 @@ __git_dequote ()
done
}
+# Prints the number of slash-separated components in a path.
+# 1: Path to count components of.
+__git_count_path_components ()
+{
+ local path="$1"
+ local relative="${path#/}"
+ relative="${relative%/}"
+ local slashes="/${relative//[^\/]}"
+ echo "${#slashes}"
+}
+
# The following function is based on code from:
#
# bash_completion - programmable completion functions for bash 3.2+
@@ -779,16 +790,39 @@ __git_tags ()
__git_dwim_remote_heads ()
{
local pfx="${1-}" cur_="${2-}" sfx="${3-}"
- local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
# employ the heuristic used by git checkout and git switch
# Try to find a remote branch that cur_es the completion word
# but only output if the branch name is unique
- __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
- --sort="refname:strip=3" \
- ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
- "refs/remotes/*/$cur_*" "refs/remotes/*/$cur_*/**" | \
- uniq -u
+ local awk_script='
+ function casemap(s) {
+ if (ENVIRON["IGNORE_CASE"])
+ return tolower(s)
+ else
+ return s
+ }
+ BEGIN {
+ split(ENVIRON["REMOTES"], remotes, /\n/)
+ for (i in remotes)
+ remotes[i] = "refs/remotes/" casemap(remotes[i])
+ cur_ = casemap(ENVIRON["CUR_"])
+ }
+ {
+ ref_case = casemap($0)
+ for (i in remotes) {
+ if (index(ref_case, remotes[i] "/" cur_) == 1) {
+ branch = substr($0, length(remotes[i] "/") + 1)
+ print ENVIRON["PFX"] branch ENVIRON["SFX"]
+ break
+ }
+ }
+ }
+ '
+ __git for-each-ref --format='%(refname)' refs/remotes/ |
+ PFX="$pfx" SFX="$sfx" CUR_="$cur_" \
+ IGNORE_CASE=${GIT_COMPLETION_IGNORE_CASE+1} \
+ REMOTES="$(__git_remotes | sort -r)" awk "$awk_script" |
+ sort | uniq -u
}
# Lists refs from the local (by default) or from a remote repository.
@@ -894,7 +928,8 @@ __git_refs ()
case "HEAD" in
$match*|$umatch*) echo "${pfx}HEAD$sfx" ;;
esac
- __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
+ local strip="$(__git_count_path_components "refs/remotes/$remote")"
+ __git for-each-ref --format="$fer_pfx%(refname:strip=$strip)$sfx" \
${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
"refs/remotes/$remote/$match*" \
"refs/remotes/$remote/$match*/**"