diff options
Diffstat (limited to 'contrib/completion/git-completion.bash')
| -rw-r--r-- | contrib/completion/git-completion.bash | 66 |
1 files changed, 53 insertions, 13 deletions
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index b3b6aa3bae..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*/**" @@ -2737,12 +2772,17 @@ __git_compute_config_vars_all () __git_config_vars_all="$(git --no-pager help --config)" } +__git_indirect() +{ + eval printf '%s' "\"\$$1\"" +} + __git_compute_first_level_config_vars_for_section () { local section="$1" __git_compute_config_vars local this_section="__git_first_level_config_vars_for_section_${section}" - test -n "${!this_section}" || + test -n "$(__git_indirect "${this_section}")" || printf -v "__git_first_level_config_vars_for_section_${section}" %s \ "$(echo "$__git_config_vars" | awk -F. "/^${section}\.[a-z]/ { print \$2 }")" } @@ -2752,7 +2792,7 @@ __git_compute_second_level_config_vars_for_section () local section="$1" __git_compute_config_vars_all local this_section="__git_second_level_config_vars_for_section_${section}" - test -n "${!this_section}" || + test -n "$(__git_indirect "${this_section}")" || printf -v "__git_second_level_config_vars_for_section_${section}" %s \ "$(echo "$__git_config_vars_all" | awk -F. "/^${section}\.</ { print \$3 }")" } @@ -2907,7 +2947,7 @@ __git_complete_config_variable_name () local section="${pfx%.*.}" __git_compute_second_level_config_vars_for_section "${section}" local this_section="__git_second_level_config_vars_for_section_${section}" - __gitcomp "${!this_section}" "$pfx" "$cur_" "$sfx" + __gitcomp "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "$sfx" return ;; branch.*) @@ -2917,7 +2957,7 @@ __git_complete_config_variable_name () __gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")" __git_compute_first_level_config_vars_for_section "${section}" local this_section="__git_first_level_config_vars_for_section_${section}" - __gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }" + __gitcomp_nl_append "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "${sfx:- }" return ;; pager.*) @@ -2934,7 +2974,7 @@ __git_complete_config_variable_name () __gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "." __git_compute_first_level_config_vars_for_section "${section}" local this_section="__git_first_level_config_vars_for_section_${section}" - __gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }" + __gitcomp_nl_append "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "${sfx:- }" return ;; submodule.*) @@ -2944,7 +2984,7 @@ __git_complete_config_variable_name () __gitcomp_nl "$(__git config -f "$(__git rev-parse --show-toplevel)/.gitmodules" --get-regexp 'submodule.*.path' | awk -F. '{print $2}')" "$pfx" "$cur_" "." __git_compute_first_level_config_vars_for_section "${section}" local this_section="__git_first_level_config_vars_for_section_${section}" - __gitcomp_nl_append "${!this_section}" "$pfx" "$cur_" "${sfx:- }" + __gitcomp_nl_append "$(__git_indirect "${this_section}")" "$pfx" "$cur_" "${sfx:- }" return ;; *.*) |
