summaryrefslogtreecommitdiff
path: root/plugins/gitfast
diff options
context:
space:
mode:
authorMarc Cornellà <marc.cornella@live.com>2019-10-24 17:57:01 +0200
committerGitHub <noreply@github.com>2019-10-24 17:57:01 +0200
commitcad48e38bfbfa6e3e0096caddf330d6fc8f1ffb9 (patch)
tree2b07ec259bbd2b1a4919245669900a87fa87a03b /plugins/gitfast
parent225425fe091ca052997833279ccc08643818c24a (diff)
parent40df67bc3b9b51caa24df5d220487043040d1f9a (diff)
downloadzsh-cad48e38bfbfa6e3e0096caddf330d6fc8f1ffb9.tar.gz
zsh-cad48e38bfbfa6e3e0096caddf330d6fc8f1ffb9.tar.bz2
zsh-cad48e38bfbfa6e3e0096caddf330d6fc8f1ffb9.zip
Merge branch 'master' into fabric_task_description
Diffstat (limited to 'plugins/gitfast')
-rw-r--r--plugins/gitfast/README.md15
-rw-r--r--plugins/gitfast/_git30
-rw-r--r--plugins/gitfast/git-completion.bash2055
-rw-r--r--plugins/gitfast/git-prompt.sh28
-rw-r--r--plugins/gitfast/gitfast.plugin.zsh4
-rwxr-xr-xplugins/gitfast/update9
-rw-r--r--plugins/gitfast/updates.patch56
7 files changed, 1335 insertions, 862 deletions
diff --git a/plugins/gitfast/README.md b/plugins/gitfast/README.md
new file mode 100644
index 000000000..84e35d77c
--- /dev/null
+++ b/plugins/gitfast/README.md
@@ -0,0 +1,15 @@
+# Gitfast plugin
+
+This plugin adds completion for Git, using the zsh completion from git.git folks, which is much faster than the official one from zsh. A lot of zsh-specific features are not supported, like descriptions for every argument, but everything the bash completion has, this one does too (as it is using it behind the scenes). Not only is it faster, it should be more robust, and updated regularly to the latest git upstream version..
+
+To use it, add `gitfast` to the plugins array in your zshrc file:
+
+```zsh
+plugins=(... gitfast)
+```
+
+## Aliases
+
+An earlier version of the plugin also loaded the git plugin. If you want to keep those
+aliases enable the [git plugin](https://github.com/robbyrussell/oh-my-zsh/tree/master/plugins/git)
+as well.
diff --git a/plugins/gitfast/_git b/plugins/gitfast/_git
index 6d1b4ecc7..886bf95d1 100644
--- a/plugins/gitfast/_git
+++ b/plugins/gitfast/_git
@@ -9,7 +9,7 @@
#
# If your script is somewhere else, you can configure it on your ~/.zshrc:
#
-# zstyle ':completion:*:*:git:*' script ~/.git-completion.sh
+# zstyle ':completion:*:*:git:*' script ~/.git-completion.zsh
#
# The recommended way to install this script is to copy to '~/.zsh/_git', and
# then add the following to your ~/.zshrc file:
@@ -30,7 +30,7 @@ if [ -z "$script" ]; then
local -a locations
local e
locations=(
- "$(dirname ${funcsourcetrace[1]%:*})/git-completion.bash"
+ $(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
'/etc/bash_completion.d/git' # fedora, old debian
'/usr/share/bash-completion/completions/git' # arch, ubuntu, new debian
'/usr/share/bash-completion/git' # gentoo
@@ -39,7 +39,7 @@ if [ -z "$script" ]; then
test -f $e && script="$e" && break
done
fi
-ZSH_VERSION='' . "$script"
+GIT_SOURCING_ZSH_COMPLETION=y . "$script"
__gitcomp ()
{
@@ -67,6 +67,15 @@ __gitcomp ()
esac
}
+__gitcomp_direct ()
+{
+ emulate -L zsh
+
+ local IFS=$'\n'
+ compset -P '*[=:]'
+ compadd -Q -- ${=1} && _ret=0
+}
+
__gitcomp_nl ()
{
emulate -L zsh
@@ -84,13 +93,22 @@ __gitcomp_nl_append ()
compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
}
+__gitcomp_file_direct ()
+{
+ emulate -L zsh
+
+ local IFS=$'\n'
+ compset -P '*[=:]'
+ compadd -f -- ${=1} && _ret=0
+}
+
__gitcomp_file ()
{
emulate -L zsh
local IFS=$'\n'
compset -P '*[=:]'
- compadd -Q -p "${2-}" -f -- ${=1} && _ret=0
+ compadd -p "${2-}" -f -- ${=1} && _ret=0
}
__git_zsh_bash_func ()
@@ -214,10 +232,8 @@ _git ()
if (( $+functions[__${service}_zsh_main] )); then
__${service}_zsh_main
- elif (( $+functions[__${service}_main] )); then
+ else
emulate ksh -c __${service}_main
- elif (( $+functions[_${service}] )); then
- emulate ksh -c _${service}
fi
let _ret && _default && _ret=0
diff --git a/plugins/gitfast/git-completion.bash b/plugins/gitfast/git-completion.bash
index e3918c87e..e087c4bf0 100644
--- a/plugins/gitfast/git-completion.bash
+++ b/plugins/gitfast/git-completion.bash
@@ -28,27 +28,58 @@
# completion style. For example '!f() { : git commit ; ... }; f' will
# tell the completion to use commit completion. This also works with aliases
# of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '".
+#
+# Compatible with bash 3.2.57.
+#
+# You can set the following environment variables to influence the behavior of
+# the completion routines:
+#
+# GIT_COMPLETION_CHECKOUT_NO_GUESS
+#
+# When set to "1", do not include "DWIM" suggestions in git-checkout
+# and git-switch completion (e.g., completing "foo" when "origin/foo"
+# exists).
case "$COMP_WORDBREAKS" in
*:*) : great ;;
*) COMP_WORDBREAKS="$COMP_WORDBREAKS:"
esac
+# Discovers the path to the git repository taking any '--git-dir=<path>' and
+# '-C <path>' options into account and stores it in the $__git_repo_path
+# variable.
+__git_find_repo_path ()
+{
+ if [ -n "$__git_repo_path" ]; then
+ # we already know where it is
+ return
+ fi
+
+ if [ -n "${__git_C_args-}" ]; then
+ __git_repo_path="$(git "${__git_C_args[@]}" \
+ ${__git_dir:+--git-dir="$__git_dir"} \
+ rev-parse --absolute-git-dir 2>/dev/null)"
+ elif [ -n "${__git_dir-}" ]; then
+ test -d "$__git_dir" &&
+ __git_repo_path="$__git_dir"
+ elif [ -n "${GIT_DIR-}" ]; then
+ test -d "${GIT_DIR-}" &&
+ __git_repo_path="$GIT_DIR"
+ elif [ -d .git ]; then
+ __git_repo_path=.git
+ else
+ __git_repo_path="$(git rev-parse --git-dir 2>/dev/null)"
+ fi
+}
+
+# Deprecated: use __git_find_repo_path() and $__git_repo_path instead
# __gitdir accepts 0 or 1 arguments (i.e., location)
# returns location of .git repo
__gitdir ()
{
if [ -z "${1-}" ]; then
- if [ -n "${__git_dir-}" ]; then
- echo "$__git_dir"
- elif [ -n "${GIT_DIR-}" ]; then
- test -d "${GIT_DIR-}" || return 1
- echo "$GIT_DIR"
- elif [ -d .git ]; then
- echo .git
- else
- git rev-parse --git-dir 2>/dev/null
- fi
+ __git_find_repo_path || return 1
+ echo "$__git_repo_path"
elif [ -d "$1/.git" ]; then
echo "$1/.git"
else
@@ -56,6 +87,78 @@ __gitdir ()
fi
}
+# Runs git with all the options given as argument, respecting any
+# '--git-dir=<path>' and '-C <path>' options present on the command line
+__git ()
+{
+ git ${__git_C_args:+"${__git_C_args[@]}"} \
+ ${__git_dir:+--git-dir="$__git_dir"} "$@" 2>/dev/null
+}
+
+# Removes backslash escaping, single quotes and double quotes from a word,
+# stores the result in the variable $dequoted_word.
+# 1: The word to dequote.
+__git_dequote ()
+{
+ local rest="$1" len ch
+
+ dequoted_word=""
+
+ while test -n "$rest"; do
+ len=${#dequoted_word}
+ dequoted_word="$dequoted_word${rest%%[\\\'\"]*}"
+ rest="${rest:$((${#dequoted_word}-$len))}"
+
+ case "${rest:0:1}" in
+ \\)
+ ch="${rest:1:1}"
+ case "$ch" in
+ $'\n')
+ ;;
+ *)
+ dequoted_word="$dequoted_word$ch"
+ ;;
+ esac
+ rest="${rest:2}"
+ ;;
+ \')
+ rest="${rest:1}"
+ len=${#dequoted_word}
+ dequoted_word="$dequoted_word${rest%%\'*}"
+ rest="${rest:$((${#dequoted_word}-$len+1))}"
+ ;;
+ \")
+ rest="${rest:1}"
+ while test -n "$rest" ; do
+ len=${#dequoted_word}
+ dequoted_word="$dequoted_word${rest%%[\\\"]*}"
+ rest="${rest:$((${#dequoted_word}-$len))}"
+ case "${rest:0:1}" in
+ \\)
+ ch="${rest:1:1}"
+ case "$ch" in
+ \"|\\|\$|\`)
+ dequoted_word="$dequoted_word$ch"
+ ;;
+ $'\n')
+ ;;
+ *)
+ dequoted_word="$dequoted_word\\$ch"
+ ;;
+ esac
+ rest="${rest:2}"
+ ;;
+ \")
+ rest="${rest:1}"
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+ done
+}
+
# The following function is based on code from:
#
# bash_completion - programmable completion functions for bash 3.2+
@@ -75,8 +178,7 @@ __gitdir ()
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# The latest version of this software can be obtained here:
#
@@ -185,6 +287,20 @@ _get_comp_words_by_ref ()
}
fi
+# Fills the COMPREPLY array with prefiltered words without any additional
+# processing.
+# Callers must take care of providing only words that match the current word
+# to be completed and adding any prefix and/or suffix (trailing space!), if
+# necessary.
+# 1: List of newline-separated matching completion words, complete with
+# prefix and suffix.
+__gitcomp_direct ()
+{
+ local IFS=$'\n'
+
+ COMPREPLY=($1)
+}
+
__gitcompappend ()
{
local x i=${#COMPREPLY[@]}
@@ -215,9 +331,32 @@ __gitcomp ()
case "$cur_" in
--*=)
;;
+ --no-*)
+ local c i=0 IFS=$' \t\n'
+ for c in $1; do
+ if [[ $c == "--" ]]; then
+ continue
+ fi
+ c="$c${4-}"
+ if [[ $c == "$cur_"* ]]; then
+ case $c in
+ --*=*|*.) ;;
+ *) c="$c " ;;
+ esac
+ COMPREPLY[i++]="${2-}$c"
+ fi
+ done
+ ;;
*)
local c i=0 IFS=$' \t\n'
for c in $1; do
+ if [[ $c == "--" ]]; then
+ c="--no-...${4-}"
+ if [[ $c == "$cur_"* ]]; then
+ COMPREPLY[i++]="${2-}$c "
+ fi
+ break
+ fi
c="$c${4-}"
if [[ $c == "$cur_"* ]]; then
case $c in
@@ -231,6 +370,48 @@ __gitcomp ()
esac
}
+# Clear the variables caching builtins' options when (re-)sourcing
+# the completion script.
+if [[ -n ${ZSH_VERSION-} ]]; then
+ unset $(set |sed -ne 's/^\(__gitcomp_builtin_[a-zA-Z0-9_][a-zA-Z0-9_]*\)=.*/\1/p') 2>/dev/null
+else
+ unset $(compgen -v __gitcomp_builtin_)
+fi
+
+# This function is equivalent to
+#
+# __gitcomp "$(git xxx --git-completion-helper) ..."
+#
+# except that the output is cached. Accept 1-3 arguments:
+# 1: the git command to execute, this is also the cache key
+# 2: extra options to be added on top (e.g. negative forms)
+# 3: options to be excluded
+__gitcomp_builtin ()
+{
+ # spaces must be replaced with underscore for multi-word
+ # commands, e.g. "git remote add" becomes remote_add.
+ local cmd="$1"
+ local incl="$2"
+ local excl="$3"
+
+ local var=__gitcomp_builtin_"${cmd/-/_}"
+ local options
+ eval "options=\$$var"
+
+ if [ -z "$options" ]; then
+ # leading and trailing spaces are significant to make
+ # option removal work correctly.
+ options=" $incl $(__git ${cmd/_/ } --git-completion-helper) " || return
+
+ for i in $excl; do
+ options="${options/ $i / }"
+ done
+ eval "$var=\"$options\""
+ fi
+
+ __gitcomp "$options"
+}
+
# Variation of __gitcomp_nl () that appends to the existing list of
# completion candidates, COMPREPLY.
__gitcomp_nl_append ()
@@ -254,6 +435,24 @@ __gitcomp_nl ()
__gitcomp_nl_append "$@"
}
+# Fills the COMPREPLY array with prefiltered paths without any additional
+# processing.
+# Callers must take care of providing only paths that match the current path
+# to be completed and adding any prefix path components, if necessary.
+# 1: List of newline-separated matching paths, complete with all prefix
+# path components.
+__gitcomp_file_direct ()
+{
+ local IFS=$'\n'
+
+ COMPREPLY=($1)
+
+ # use a hack to enable file mode in bash < 4
+ compopt -o filenames +o nospace 2>/dev/null ||
+ compgen -f /non-existing-dir/ >/dev/null ||
+ true
+}
+
# Generates completion reply with compgen from newline-separated possible
# completion filenames.
# It accepts 1 to 3 arguments:
@@ -273,7 +472,8 @@ __gitcomp_file ()
# use a hack to enable file mode in bash < 4
compopt -o filenames +o nospace 2>/dev/null ||
- compgen -f /non-existing-dir/ > /dev/null
+ compgen -f /non-existing-dir/ >/dev/null ||
+ true
}
# Execute 'git ls-files', unless the --committable option is specified, in
@@ -283,11 +483,13 @@ __gitcomp_file ()
__git_ls_files_helper ()
{
if [ "$2" == "--committable" ]; then
- git -C "$1" diff-index --name-only --relative HEAD
+ __git -C "$1" -c core.quotePath=false diff-index \
+ --name-only --relative HEAD -- "${3//\\/\\\\}*"
else
# NOTE: $2 is not quoted in order to support multiple options
- git -C "$1" ls-files --exclude-standard $2
- fi 2>/dev/null
+ __git -C "$1" -c core.quotePath=false ls-files \
+ --exclude-standard $2 -- "${3//\\/\\\\}*"
+ fi
}
@@ -297,101 +499,283 @@ __git_ls_files_helper ()
# If provided, only files within the specified directory are listed.
# Sub directories are never recursed. Path must have a trailing
# slash.
+# 3: List only paths matching this path component (optional).
__git_index_files ()
{
- local dir="$(__gitdir)" root="${2-.}" file
+ local root="$2" match="$3"
- if [ -d "$dir" ]; then
- __git_ls_files_helper "$root" "$1" |
- while read -r file; do
- case "$file" in
- ?*/*) echo "${file%%/*}" ;;
- *) echo "$file" ;;
- esac
- done | sort | uniq
- fi
+ __git_ls_files_helper "$root" "$1" "$match" |
+ awk -F / -v pfx="${2//\\/\\\\}" '{
+ paths[$1] = 1
+ }
+ END {
+ for (p in paths) {
+ if (substr(p, 1, 1) != "\"") {
+ # No special characters, easy!
+ print pfx p
+ continue
+ }
+
+ # The path is quoted.
+ p = dequote(p)
+ if (p == "")
+ continue
+
+ # Even when a directory name itself does not contain
+ # any special characters, it will still be quoted if
+ # any of its (stripped) trailing path components do.
+ # Because of this we may have seen the same direcory
+ # both quoted and unquoted.
+ if (p in paths)
+ # We have seen the same directory unquoted,
+ # skip it.
+ continue
+ else
+ print pfx p
+ }
+ }
+ function dequote(p, bs_idx, out, esc, esc_idx, dec) {
+ # Skip opening double quote.
+ p = substr(p, 2)
+
+ # Interpret backslash escape sequences.
+ while ((bs_idx = index(p, "\\")) != 0) {
+ out = out substr(p, 1, bs_idx - 1)
+ esc = substr(p, bs_idx + 1, 1)
+ p = substr(p, bs_idx + 2)
+
+ if ((esc_idx = index("abtvfr\"\\", esc)) != 0) {
+ # C-style one-character escape sequence.
+ out = out substr("\a\b\t\v\f\r\"\\",
+ esc_idx, 1)
+ } else if (esc == "n") {
+ # Uh-oh, a newline character.
+ # We cant reliably put a pathname
+ # containing a newline into COMPREPLY,
+ # and the newline would create a mess.
+ # Skip this path.
+ return ""
+ } else {
+ # Must be a \nnn octal value, then.
+ dec = esc * 64 + \
+ substr(p, 1, 1) * 8 + \
+ substr(p, 2, 1)
+ out = out sprintf("%c", dec)
+ p = substr(p, 3)
+ }
+ }
+ # Drop closing double quote, if there is one.
+ # (There isnt any if this is a directory, as it was
+ # already stripped with the trailing path components.)
+ if (substr(p, length(p), 1) == "\"")
+ out = out substr(p, 1, length(p) - 1)
+ else
+ out = out p
+
+ return out
+ }'
}
+# __git_complete_index_file requires 1 argument:
+# 1: the options to pass to ls-file
+#
+# The exception is --committable, which finds the files appropriate commit.
+__git_complete_index_file ()
+{
+ local dequoted_word pfx="" cur_
+
+ __git_dequote "$cur"
+
+ case "$dequoted_word" in
+ ?*/*)
+ pfx="${dequoted_word%/*}/"
+ cur_="${dequoted_word##*/}"
+ ;;
+ *)
+ cur_="$dequoted_word"
+ esac
+
+ __gitcomp_file_direct "$(__git_index_files "$1" "$pfx" "$cur_")"
+}
+
+# Lists branches from the local repository.
+# 1: A prefix to be added to each listed branch (optional).
+# 2: List only branches matching this word (optional; list all branches if
+# unset or empty).
+# 3: A suffix to be appended to each listed branch (optional).
__git_heads ()
{
- local dir="$(__gitdir)"
- if [ -d "$dir" ]; then
- git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
- refs/heads
- return
- fi
+ local pfx="${1-}" cur_="${2-}" sfx="${3-}"
+
+ __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
+ "refs/heads/$cur_*" "refs/heads/$cur_*/**"
}
+# Lists tags from the local repository.
+# Accepts the same positional parameters as __git_heads() above.
__git_tags ()
{
- local dir="$(__gitdir)"
- if [ -d "$dir" ]; then
- git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
- refs/tags
- return
- fi
+ local pfx="${1-}" cur_="${2-}" sfx="${3-}"
+
+ __git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
+ "refs/tags/$cur_*" "refs/tags/$cur_*/**"
}
-# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments
-# presence of 2nd argument means use the guess heuristic employed
-# by checkout for tracking branches
+# Lists refs from the local (by default) or from a remote repository.
+# It accepts 0, 1 or 2 arguments:
+# 1: The remote to list refs from (optional; ignored, if set but empty).
+# 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: A prefix to be added to each listed ref (optional).
+# 4: List only refs matching this word (optional; list all refs if unset or
+# empty).
+# 5: A suffix to be appended to each listed ref (optional; ignored, if set
+# but empty).
+#
+# Use __git_complete_refs() instead.
__git_refs ()
{
- local i hash dir="$(__gitdir "${1-}")" track="${2-}"
+ local i hash dir track="${2-}"
+ local list_refs_from=path remote="${1-}"
local format refs
- if [ -d "$dir" ]; then
- case "$cur" in
+ local pfx="${3-}" cur_="${4-$cur}" sfx="${5-}"
+ local match="${4-}"
+ local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
+
+ __git_find_repo_path
+ dir="$__git_repo_path"
+
+ if [ -z "$remote" ]; then
+ if [ -z "$dir" ]; then
+ return
+ fi
+ else
+ if __git_is_configured_remote "$remote"; then
+ # configured remote takes precedence over a
+ # local directory with the same name
+ list_refs_from=remote
+ elif [ -d "$remote/.git" ]; then
+ dir="$remote/.git"
+ elif [ -d "$remote" ]; then
+ dir="$remote"
+ else
+ list_refs_from=url
+ fi
+ fi
+
+ if [ "$list_refs_from" = path ]; then
+ if [[ "$cur_" == ^* ]]; then
+ pfx="$pfx^"
+ fer_pfx="$fer_pfx^"
+ cur_=${cur_#^}
+ match=${match#^}
+ fi
+ case "$cur_" in
refs|refs/*)
format="refname"
- refs="${cur%/*}"
+ refs=("$match*" "$match*/**")
track=""
;;
*)
- for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do
- if [ -e "$dir/$i" ]; then echo $i; fi
+ for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD REBASE_HEAD; do
+ case "$i" in
+ $match*)
+ if [ -e "$dir/$i" ]; then
+ echo "$pfx$i$sfx"
+ fi
+ ;;
+ esac
done
- format="refname:short"
- refs="refs/tags refs/heads refs/remotes"
+ format="refname:strip=2"
+ refs=("refs/tags/$match*" "refs/tags/$match*/**"
+ "refs/heads/$match*" "refs/heads/$match*/**"
+ "refs/remotes/$match*" "refs/remotes/$match*/**")
;;
esac
- git --git-dir="$dir" for-each-ref --format="%($format)" \
- $refs
+ __git_dir="$dir" __git for-each-ref --format="$fer_pfx%($format)$sfx" \
+ "${refs[@]}"
if [ -n "$track" ]; then
# employ the heuristic used by git checkout
# Try to find a remote branch that matches the completion word
# but only output if the branch name is unique
- local ref entry
- git --git-dir="$dir" for-each-ref --shell --format="ref=%(refname:short)" \
- "refs/remotes/" | \
- while read -r entry; do
- eval "$entry"
- ref="${ref#*/}"
- if [[ "$ref" == "$cur"* ]]; then
- echo "$ref"
- fi
- done | sort | uniq -u
+ __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
+ --sort="refname:strip=3" \
+ "refs/remotes/*/$match*" "refs/remotes/*/$match*/**" | \
+ uniq -u
fi
return
fi
- case "$cur" in
+ case "$cur_" in
refs|refs/*)
- git ls-remote "$dir" "$cur*" 2>/dev/null | \
+ __git ls-remote "$remote" "$match*" | \
while read -r hash i; do
case "$i" in
*^{}) ;;
- *) echo "$i" ;;
+ *) echo "$pfx$i$sfx" ;;
esac
done
;;
*)
- echo "HEAD"
- git for-each-ref --format="%(refname:short)" -- \
- "refs/remotes/$dir/" 2>/dev/null | sed -e "s#^$dir/##"
+ if [ "$list_refs_from" = remote ]; then
+ case "HEAD" in
+ $match*) echo "${pfx}HEAD$sfx" ;;
+ esac
+ __git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
+ "refs/remotes/$remote/$match*" \
+ "refs/remotes/$remote/$match*/**"
+ else
+ local query_symref
+ case "HEAD" in
+ $match*) query_symref="HEAD" ;;
+ esac
+ __git ls-remote "$remote" $query_symref \
+ "refs/tags/$match*" "refs/heads/$match*" \
+ "refs/remotes/$match*" |
+ while read -r hash i; do
+ case "$i" in
+ *^{}) ;;
+ refs/*) echo "$pfx${i#refs/*/}$sfx" ;;
+ *) echo "$pfx$i$sfx" ;; # symbolic refs
+ esac
+ done
+ fi
;;
esac
}
+# Completes refs, short and long, local and remote, symbolic and pseudo.
+#
+# Usage: __git_complete_refs [<option>]...
+# --remote=<remote>: The remote to list refs from, can be the name of a
+# configured remote, a path, or a URL.
+# --track: List unique remote branches for 'git checkout's tracking DWIMery.
+# --pfx=<prefix>: A prefix to be added to each ref.
+# --cur=<word>: The current ref to be completed. Defaults to the current
+# word to be completed.
+# --sfx=<suffix>: A suffix to be appended to each ref instead of the default
+# space.
+__git_complete_refs ()
+{
+ local remote track pfx cur_="$cur" sfx=" "
+
+ while test $# != 0; do
+ case "$1" in
+ --remote=*) remote="${1##--remote=}" ;;
+ --track) track="yes" ;;
+ --pfx=*) pfx="${1##--pfx=}" ;;
+ --cur=*) cur_="${1##--cur=}" ;;
+ --sfx=*) sfx="${1##--sfx=}" ;;
+ *) return 1 ;;
+ esac
+ shift
+ done
+
+ __gitcomp_direct "$(__git_refs "$remote" "$track" "$pfx" "$cur_" "$sfx")"
+}
+
# __git_refs2 requires 1 argument (to pass to __git_refs)
+# Deprecated: use __git_complete_fetch_refspecs() instead.
__git_refs2 ()
{
local i
@@ -400,11 +784,29 @@ __git_refs2 ()
done
}
+# Completes refspecs for fetching from a remote repository.
+# 1: The remote repository.
+# 2: A prefix to be added to each listed refspec (optional).
+# 3: The ref to be completed as a refspec instead of the current word to be
+# completed (optional)
+# 4: A suffix to be appended to each listed refspec instead of the default
+# space (optional).
+__git_complete_fetch_refspecs ()
+{
+ local i remote="$1" pfx="${2-}" cur_="${3-$cur}" sfx="${4- }"
+
+ __gitcomp_direct "$(
+ for i in $(__git_refs "$remote" "" "" "$cur_") ; do
+ echo "$pfx$i:$i$sfx"
+ done
+ )"
+}
+
# __git_refs_remotes requires 1 argument (to pass to ls-remote)
__git_refs_remotes ()
{
local i hash
- git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \
+ __git ls-remote "$1" 'refs/heads/*' | \
while read -r hash i; do
echo "$i:refs/remotes/$1/${i#refs/heads/}"
done
@@ -412,14 +814,26 @@ __git_refs_remotes ()
__git_remotes ()
{
- local d="$(__gitdir)"
- test -d "$d/remotes" && ls -1 "$d/remotes"
- git --git-dir="$d" remote
+ __git_find_repo_path
+ test -d "$__git_repo_path/remotes" && ls -1 "$__git_repo_path/remotes"
+ __git remote
+}
+
+# Returns true if $1 matches the name of a configured remote, false otherwise.
+__git_is_configured_remote ()
+{
+ local remote
+ for remote in $(__git_remotes); do
+ if [ "$remote" = "$1" ]; then
+ return 0
+ fi
+ done
+ return 1
}
__git_list_merge_strategies ()
{
- git merge -s help 2>&1 |
+ LANG=C LC_ALL=C git merge -s help 2>&1 |
sed -n -e '/[Aa]vailable strategies are: /,/^$/{
s/\.$//
s/.*://
@@ -441,9 +855,14 @@ __git_compute_merge_strategies ()
__git_merge_strategies=$(__git_list_merge_strategies)
}
+__git_merge_strategy_options="ours theirs subtree subtree= patience
+ histogram diff-algorithm= ignore-space-change ignore-all-space
+ ignore-space-at-eol renormalize no-renormalize no-renames
+ find-renames find-renames= rename-threshold="
+
__git_complete_revlist_file ()
{
- local pfx ls ref cur_="$cur"
+ local dequoted_word pfx ls ref cur_="$cur"
case "$cur_" in
*..?*:*)
return
@@ -451,14 +870,18 @@ __git_complete_revlist_file ()
?*:*)
ref="${cur_%%:*}"
cur_="${cur_#*:}"
- case "$cur_" in
+
+ __git_dequote "$cur_"
+
+ case "$dequoted_word" in
?*/*)
- pfx="${cur_%/*}"
- cur_="${cur_##*/}"
+ pfx="${dequoted_word%/*}"
+ cur_="${dequoted_word##*/}"
ls="$ref:$pfx"
pfx="$pfx/"
;;
*)
+ cur_="$dequoted_word"
ls="$ref"
;;
esac
@@ -468,56 +891,25 @@ __git_complete_revlist_file ()
*) pfx="$ref:$pfx" ;;
esac
- __gitcomp_nl "$(git --git-dir="$(__gitdir)" ls-tree "$ls" 2>/dev/null \
- | sed '/^100... blob /{
- s,^.* ,,
- s,$, ,
- }
- /^120000 blob /{
- s,^.* ,,
- s,$, ,
- }
- /^040000 tree /{
- s,^.* ,,
- s,$,/,
- }
- s/^.* //')" \
- "$pfx" "$cur_" ""
+ __gitcomp_file "$(__git ls-tree "$ls" \
+ | sed 's/^.* //
+ s/$//')" \
+ "$pfx" "$cur_"
;;
*...*)
pfx="${cur_%...*}..."
cur_="${cur_#*...}"
- __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
+ __git_complete_refs --pfx="$pfx" --cur="$cur_"
;;
*..*)
pfx="${cur_%..*}.."
cur_="${cur_#*..}"
- __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
+ __git_complete_refs --pfx="$pfx" --cur="$cur_"
;;
*)
- __gitcomp_nl "$(__git_refs)"
- ;;
- esac
-}
-
-
-# __git_complete_index_file requires 1 argument:
-# 1: the options to pass to ls-file
-#
-# The exception is --committable, which finds the files appropriate commit.
-__git_complete_index_file ()
-{
- local pfx="" cur_="$cur"
-
- case "$cur_" in
- ?*/*)
- pfx="${cur_%/*}"
- cur_="${cur_##*/}"
- pfx="${pfx}/"
+ __git_complete_refs
;;
esac
-
- __gitcomp_file "$(__git_index_files "$1" ${pfx:+"$pfx"})" "$pfx" "$cur_"
}
__git_complete_file ()
@@ -541,6 +933,7 @@ __git_complete_remote_or_refspec ()
i="${words[c]}"
case "$i" in
--mirror) [ "$cmd" = "push" ] && no_complete_refspec=1 ;;
+ -d|--delete) [ "$cmd" = "push" ] && lhs=0 ;;
--all)
case "$cmd" in
push) no_complete_refspec=1 ;;
@@ -550,6 +943,7 @@ __git_complete_remote_or_refspec ()
*) ;;
esac
;;
+ --multiple) no_complete_refspec=1; break ;;
-*) ;;
*) remote="$i"; break ;;
esac
@@ -580,23 +974,23 @@ __git_complete_remote_or_refspec ()
case "$cmd" in
fetch)
if [ $lhs = 1 ]; then
- __gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
+ __git_complete_fetch_refspecs "$remote" "$pfx" "$cur_"
else
- __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
+ __git_complete_refs --pfx="$pfx" --cur="$cur_"
fi
;;
pull|remote)
if [ $lhs = 1 ]; then
- __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
+ __git_complete_refs --remote="$remote" --pfx="$pfx" --cur="$cur_"
else
- __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
+ __git_complete_refs --pfx="$pfx" --cur="$cur_"
fi
;;
push)
if [ $lhs = 1 ]; then
- __gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
+ __git_complete_refs --pfx="$pfx" --cur="$cur_"
else
- __gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
+ __git_complete_refs --remote="$remote" --pfx="$pfx" --cur="$cur_"
fi
;;
esac
@@ -609,136 +1003,30 @@ __git_complete_strategy ()
-s|--strategy)
__gitcomp "$__git_merge_strategies"
return 0
+ ;;
+ -X)
+ __gitcomp "$__git_merge_strategy_options"
+ return 0
+ ;;
esac
case "$cur" in
--strategy=*)
__gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}"
return 0
;;
+ --strategy-option=*)
+ __gitcomp "$__git_merge_strategy_options" "" "${cur##--strategy-option=}"
+ return 0
+ ;;
esac
return 1
}
-__git_commands () {
- if test -n "${GIT_TESTING_COMMAND_COMPLETION:-}"
- then
- printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}"
- else
- git help -a|egrep '^ [a-zA-Z0-9]'
- fi
-}
-
-__git_list_all_commands ()
-{
- local i IFS=" "$'\n'
- for i in $(__git_commands)
- do
- case $i in
- *--*) : helper pattern;;
- *) echo $i;;
- esac
- done
-}
-
__git_all_commands=
__git_compute_all_commands ()
{
test -n "$__git_all_commands" ||
- __git_all_commands=$(__git_list_all_commands)
-}
-
-__git_list_porcelain_commands ()
-{
- local i IFS=" "$'\n'
- __git_compute_all_commands
- for i in $__git_all_commands
- do
- case $i in
- *--*) : helper pattern;;
- applymbox) : ask gittus;;
- applypatch) : ask gittus;;
- archimport) : import;;
- cat-file) : plumbing;;
- check-attr) : plumbing;;
- check-ignore) : plumbing;;
- check-mailmap) : plumbing;;
- check-ref-format) : plumbing;;
- checkout-index) : plumbing;;
- column) : internal helper;;
- commit-tree) : plumbing;;
- count-objects) : infrequent;;
- credential) : credentials;;
- credential-*) : credentials helper;;
- cvsexportcommit) : export;;
- cvsimport) : import;;
- cvsserver) : daemon;;
- daemon) : daemon;;
- diff-files) : plumbing;;
- diff-index) : plumbing;;
- diff-tree) : plumbing;;
- fast-import) : import;;
- fast-export) : export;;
- fsck-objects) : plumbing;;
- fetch-pack) : plumbing;;
- fmt-merge-msg) : plumbing;;
- for-each-ref) : plumbing;;
- hash-object) : plumbing;;
- http-*) : transport;;
- index-pack) : plumbing;;
- init-db) : deprecated;;
- local-fetch) : plumbing;;
- ls-files) : plumbing;;
- ls-remote) : plumbing;;
- ls-tree) : plumbing;;
- mailinfo) : plumbing;;
- mailsplit) : plumbing;;
- merge-*) : plumbing;;
- mktree) : plumbing;;
- mktag) : plumbing;;
- pack-objects) : plumbing;;
- pack-redundant) : plumbing;;
- pack-refs) : plumbing;;
- parse-remote) : plumbing;;
- patch-id) : plumbing;;
- prune) : plumbing;;
- prune-packed) : plumbing;;
- quiltimport) : import;;
- read-tree) : plumbing;;
- receive-pack) : plumbing;;
- remote-*) : transport;;
- rerere) : plumbing;;
- rev-list) : plumbing;;
- rev-parse) : plumbing;;
- runstatus) : plumbing;;
- sh-setup) : internal;;
- shell) : daemon;;
- show-ref) : plumbing;;
- send-pack) : plumbing;;
- show-index) : plumbing;;
- ssh-*) : transport;;
- stripspace) : plumbing;;
- symbolic-ref) : plumbing;;
- unpack-file) : plumbing;;
- unpack-objects) : plumbing;;
- update-index) : plumbing;;
- update-ref) : plumbing;;
- update-server-info) : daemon;;
- upload-archive) : plumbing;;
- upload-pack) : plumbing;;
- write-tree) : plumbing;;
- var) : infrequent;;
- verify-pack) : infrequent;;
- verify-tag) : plumbing;;
- *) echo $i;;
- esac
- done
-}
-
-__git_porcelain_commands=
-__git_compute_porcelain_commands ()
-{
- test -n "$__git_porcelain_commands" ||
- __git_porcelain_commands=$(__git_list_porcelain_commands)
+ __git_all_commands=$(__git --list-cmds=main,others,alias,nohelpers)
}
# Lists all set config variables starting with the given section prefix,
@@ -746,7 +1034,7 @@ __git_compute_porcelain_commands ()
__git_get_config_variables ()
{
local section="$1" i IFS=$'\n'
- for i in $(git --git-dir="$(__gitdir)" config --name-only --get-regexp "^$section\..*" 2>/dev/null); do
+ for i in $(__git config --name-only --get-regexp "^$section\..*"); do
echo "${i#$section.}"
done
}
@@ -756,16 +1044,10 @@ __git_pretty_aliases ()
__git_get_config_variables "pretty"
}
-__git_aliases ()
-{
- __git_get_config_variables "alias"
-}
-
# __git_aliased_command requires 1 argument
__git_aliased_command ()
{
- local word cmdline=$(git --git-dir="$(__gitdir)" \
- config --get "alias.$1")
+ local word cmdline=$(__git config --get "alias.$1")
for word in $cmdline; do
case "$word" in
\!gitk|gitk)
@@ -803,6 +1085,50 @@ __git_find_on_cmdline ()
done
}
+# Echo the value of an option set on the command line or config
+#
+# $1: short option name
+# $2: long option name including =
+# $3: list of possible values
+# $4: config string (optional)
+#
+# example:
+# result="$(__git_get_option_value "-d" "--do-something=" \
+# "yes no" "core.doSomething")"
+#
+# result is then either empty (no option set) or "yes" or "no"
+#
+# __git_get_option_value requires 3 arguments
+__git_get_option_value ()
+{
+ local c short_opt long_opt val
+ local result= values config_key word
+
+ short_opt="$1"
+ long_opt="$2"
+ values="$3"
+ config_key="$4"
+
+ ((c = $cword - 1))
+ while [ $c -ge 0 ]; do
+ word="${words[c]}"
+ for val in $values; do
+ if [ "$short_opt$val" = "$word" ] ||
+ [ "$long_opt$val" = "$word" ]; then
+ result="$val"
+ break 2
+ fi
+ done
+ ((c--))
+ done
+
+ if [ -n "$config_key" ] && [ -z "$result" ]; then
+ result="$(__git config "$config_key")"
+ fi
+
+ echo "$result"
+}
+
__git_has_doubledash ()
{
local c=1
@@ -853,12 +1179,14 @@ __git_count_arguments ()
}
__git_whitespacelist="nowarn warn error error-all fix"
+__git_patchformat="mbox stgit stgit-series hg mboxrd"
+__git_am_inprogress_options="--skip --continue --resolved --abort --quit --show-current-patch"
_git_am ()
{
- local dir="$(__gitdir)"
- if [ -d "$dir"/rebase-apply ]; then
- __gitcomp "--skip --continue --resolved --abort"
+ __git_find_repo_path
+ if [ -d "$__git_repo_path"/rebase-apply ]; then
+ __gitcomp "$__git_am_inprogress_options"
return
fi
case "$cur" in
@@ -866,13 +1194,13 @@ _git_am ()
__gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}"
return
;;
+ --patch-format=*)
+ __gitcomp "$__git_patchformat" "" "${cur##--patch-format=}"
+ return
+ ;;
--*)
- __gitcomp "
- --3way --committer-date-is-author-date --ignore-date
- --ignore-whitespace --ignore-space-change
- --interactive --keep --no-utf8 --signoff --utf8
- --whitespace= --scissors
- "
+ __gitcomp_builtin am "" \
+ "$__git_am_inprogress_options"
return
esac
}
@@ -885,13 +1213,7 @@ _git_apply ()
return
;;
--*)
- __gitcomp "
- --stat --numstat --summary --check --index
- --cached --index-info --reverse --reject --unidiff-zero
- --apply --no-add --exclude=
- --ignore-whitespace --ignore-space-change
- --whitespace= --inaccurate-eof --verbose
- "
+ __gitcomp_builtin apply
return
esac
}
@@ -899,16 +1221,21 @@ _git_apply ()
_git_add ()
{
case "$cur" in
+ --chmod=*)
+ __gitcomp "+x -x" "" "${cur##--chmod=}"
+ return
+ ;;
--*)
- __gitcomp "
- --interactive --refresh --patch --update --dry-run
- --ignore-errors --intent-to-add
- "
+ __gitcomp_builtin add
return
esac
- # XXX should we check for --update and --all options ?
- __git_complete_index_file "--others --modified --directory --no-empty-directory"
+ local complete_opt="--others --modified --directory --no-empty-directory"
+ if test -n "$(__git_find_on_cmdline "-u --update")"
+ then
+ complete_opt="--modified"
+ fi
+ __git_complete_index_file "$complete_opt"
}
_git_archive ()
@@ -925,7 +1252,7 @@ _git_archive ()
--*)
__gitcomp "
--format= --list --verbose
- --prefix= --remote= --exec=
+ --prefix= --remote= --exec= --output
"
return
;;
@@ -940,7 +1267,8 @@ _git_bisect ()
local subcommands="start bad good skip reset visualize replay log run"
local subcommand="$(__git_find_on_cmdline "$subcommands")"
if [ -z "$subcommand" ]; then
- if [ -f "$(__gitdir)"/BISECT_START ]; then
+ __git_find_repo_path
+ if [ -f "$__git_repo_path"/BISECT_START ]; then
__gitcomp "$subcommands"
else
__gitcomp "replay start"
@@ -950,13 +1278,15 @@ _git_bisect ()
case "$subcommand" in
bad|good|reset|skip|start)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
;;
*)
;;
esac
}
+__git_ref_fieldlist="refname objecttype objectsize objectname upstream push HEAD symref"
+
_git_branch ()
{
local i c=1 only_local_ref="n" has_r="n"
@@ -964,29 +1294,24 @@ _git_branch ()
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
- -d|-m) only_local_ref="y" ;;
- -r) has_r="y" ;;
+ -d|--delete|-m|--move) only_local_ref="y" ;;
+ -r|--remotes) has_r="y" ;;
esac
((c++))
done
case "$cur" in
--set-upstream-to=*)
- __gitcomp_nl "$(__git_refs)" "" "${cur##--set-upstream-to=}"
+ __git_complete_refs --cur="${cur##--set-upstream-to=}"
;;
--*)
- __gitcomp "
- --color --no-color --verbose --abbrev= --no-abbrev
- --track --no-track --contains --merged --no-merged
- --set-upstream-to= --edit-description --list
- --unset-upstream
- "
+ __gitcomp_builtin branch
;;
*)
if [ $only_local_ref = "y" -a $has_r = "n" ]; then
- __gitcomp_nl "$(__git_heads)"
+ __gitcomp_direct "$(__git_heads "" "$cur" " ")"
else
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
fi
;;
esac
@@ -1021,41 +1346,40 @@ _git_checkout ()
__gitcomp "diff3 merge" "" "${cur##--conflict=}"
;;
--*)
- __gitcomp "
- --quiet --ours --theirs --track --no-track --merge
- --conflict= --orphan --patch
- "
+ __gitcomp_builtin checkout
;;
*)
# check if --track, --no-track, or --no-guess was specified
# if so, disable DWIM mode
- local flags="--track --no-track --no-guess" track=1
- if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
- track=''
+ local flags="--track --no-track --no-guess" track_opt="--track"
+ if [ "$GIT_COMPLETION_CHECKOUT_NO_GUESS" = "1" ] ||
+ [ -n "$(__git_find_on_cmdline "$flags")" ]; then
+ track_opt=''
fi
- __gitcomp_nl "$(__git_refs '' $track)"
+ __git_complete_refs $track_opt
;;
esac
}
-_git_cherry ()
-{
- __gitcomp_nl "$(__git_refs)"
-}
+__git_cherry_pick_inprogress_options="--continue --quit --abort"
_git_cherry_pick ()
{
- local dir="$(__gitdir)"
- if [ -f "$dir"/CHERRY_PICK_HEAD ]; then
- __gitcomp "--continue --quit --abort"
+ __git_find_repo_path
+ if [ -f "$__git_repo_path"/CHERRY_PICK_HEAD ]; then
+ __gitcomp "$__git_cherry_pick_inprogress_options"
return
fi
+
+ __git_complete_strategy && return
+
case "$cur" in
--*)
- __gitcomp "--edit --no-commit --signoff --strategy= --mainline"
+ __gitcomp_builtin cherry-pick "" \
+ "$__git_cherry_pick_inprogress_options"
;;
*)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
;;
esac
}
@@ -1064,7 +1388,7 @@ _git_clean ()
{
case "$cur" in
--*)
- __gitcomp "--dry-run --quiet"
+ __gitcomp_builtin clean
return
;;
esac
@@ -1077,32 +1401,19 @@ _git_clone ()
{
case "$cur" in
--*)
- __gitcomp "
- --local
- --no-hardlinks
- --shared
- --reference
- --quiet
- --no-checkout
- --bare
- --mirror
- --origin
- --upload-pack
- --template=
- --depth
- --single-branch
- --branch
- "
+ __gitcomp_builtin clone
return
;;
esac
}
+__git_untracked_file_modes="all no normal"
+
_git_commit ()
{
case "$prev" in
-c|-C)
- __gitcomp_nl "$(__git_refs)" "" "${cur}"
+ __git_complete_refs
return
;;
esac
@@ -1115,27 +1426,19 @@ _git_commit ()
;;
--reuse-message=*|--reedit-message=*|\
--fixup=*|--squash=*)
- __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
+ __git_complete_refs --cur="${cur#*=}"
return
;;
--untracked-files=*)
- __gitcomp "all no normal" "" "${cur##--untracked-files=}"
+ __gitcomp "$__git_untracked_file_modes" "" "${cur##--untracked-files=}"
return
;;
--*)
- __gitcomp "
- --all --author= --signoff --verify --no-verify
- --edit --no-edit
- --amend --include --only --interactive
- --dry-run --reuse-message= --reedit-message=
- --reset-author --file= --message= --template=
- --cleanup= --untracked-files --untracked-files=
- --verbose --quiet --fixup= --squash=
- "
+ __gitcomp_builtin commit
return
esac
- if git rev-parse --verify --quiet HEAD >/dev/null; then
+ if __git rev-parse --verify --quiet HEAD >/dev/null; then
__git_complete_index_file "--committable"
else
# This is the first commit
@@ -1147,22 +1450,21 @@ _git_describe ()
{
case "$cur" in
--*)
- __gitcomp "
- --all --tags --contains --abbrev= --candidates=
- --exact-match --debug --long --match --always
- "
+ __gitcomp_builtin describe
return
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
__git_diff_algorithms="myers minimal patience histogram"
+__git_diff_submodule_formats="diff log short"
+
__git_diff_common_options="--stat --numstat --shortstat --summary
--patch-with-stat --name-only --name-status --color
--no-color --color-words --no-renames --check
--full-index --binary --abbrev --diff-filter=
- --find-copies-harder
+ --find-copies-harder --ignore-cr-at-eol
--text --ignore-space-at-eol --ignore-space-change
--ignore-all-space --ignore-blank-lines --exit-code
--quiet --ext-diff --no-ext-diff
@@ -1173,6 +1475,7 @@ __git_diff_common_options="--stat --numstat --shortstat --summary
--dirstat --dirstat= --dirstat-by-file
--dirstat-by-file= --cumulative
--diff-algorithm=
+ --submodule --submodule= --ignore-submodules
"
_git_diff ()
@@ -1184,6 +1487,10 @@ _git_diff ()
__gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
return
;;
+ --submodule=*)
+ __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
+ return
+ ;;
--*)
__gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
--base --ours --theirs --no-index
@@ -1196,7 +1503,8 @@ _git_diff ()
}
__git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff
- tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc codecompare
+ tkdiff vimdiff gvimdiff xxdiff araxis p4merge bc
+ codecompare smerge
"
_git_difftool ()
@@ -1209,11 +1517,11 @@ _git_difftool ()
return
;;
--*)
- __gitcomp "--cached --staged --pickaxe-all --pickaxe-regex
- --base --ours --theirs
- --no-renames --diff-filter= --find-copies-harder
- --relative --ignore-submodules
- --tool="
+ __gitcomp_builtin difftool "$__git_diff_common_options
+ --base --cached --ours --theirs
+ --pickaxe-all --pickaxe-regex
+ --relative --staged
+ "
return
;;
esac
@@ -1222,11 +1530,6 @@ _git_difftool ()
__git_fetch_recurse_submodules="yes on-demand no"
-__git_fetch_options="
- --quiet --verbose --append --upload-pack --force --keep --depth=
- --tags --no-tags --all --prune --dry-run --recurse-submodules=
-"
-
_git_fetch ()
{
case "$cur" in
@@ -1234,21 +1537,21 @@ _git_fetch ()
__gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}"
return
;;
+ --filter=*)
+ __gitcomp "blob:none blob:limit= sparse:oid=" "" "${cur##--filter=}"
+ return
+ ;;
--*)
- __gitcomp "$__git_fetch_options"
+ __gitcomp_builtin fetch
return
;;
esac
__git_complete_remote_or_refspec
}
-__git_format_patch_options="
- --stdout --attach --no-attach --thread --thread= --no-thread
- --numbered --start-number --numbered-files --keep-subject --signoff
- --signature --no-signature --in-reply-to= --cc= --full-index --binary
- --not --all --cover-letter --no-prefix --src-prefix= --dst-prefix=
- --inline --suffix= --ignore-if-in-upstream --subject-prefix=
- --output-directory --reroll-count --to= --quiet --notes
+__git_format_patch_extra_options="
+ --full-index --not --all --no-prefix --src-prefix=
+ --dst-prefix= --notes
"
_git_format_patch ()
@@ -1261,7 +1564,7 @@ _git_format_patch ()
return
;;
--*)
- __gitcomp "$__git_format_patch_options"
+ __gitcomp_builtin format-patch "$__git_format_patch_extra_options"
return
;;
esac
@@ -1272,20 +1575,7 @@ _git_fsck ()
{
case "$cur" in
--*)
- __gitcomp "
- --tags --root --unreachable --cache --no-reflogs --full
- --strict --verbose --lost-found
- "
- return
- ;;
- esac
-}
-
-_git_gc ()
-{
- case "$cur" in
- --*)
- __gitcomp "--prune --aggressive"
+ __gitcomp_builtin fsck
return
;;
esac
@@ -1296,8 +1586,43 @@ _git_gitk ()
_gitk
}
-__git_match_ctag() {
- awk "/^${1//\//\\/}/ { print \$1 }" "$2"
+# Lists matching symbol names from a tag (as in ctags) file.
+# 1: List symbol names matching this word.
+# 2: The tag file to list symbol names from.
+# 3: A prefix to be added to each listed symbol name (optional).
+# 4: A suffix to be appended to each listed symbol name (optional).
+__git_match_ctag () {
+ awk -v pfx="${3-}" -v sfx="${4-}" "
+ /^${1//\//\\/}/ { print pfx \$1 sfx }
+ " "$2"
+}
+
+# Complete symbol names from a tag file.
+# Usage: __git_complete_symbol [<option>]...
+# --tags=<file>: The tag file to list symbol names from instead of the
+# default "tags".
+# --pfx=<prefix>: A prefix to be added to each symbol name.
+# --cur=<word>: The current symbol name to be completed. Defaults to
+# the current word to be completed.
+# --sfx=<suffix>: A suffix to be appended to each symbol name instead
+# of the default space.
+__git_complete_symbol () {
+ local tags=tags pfx="" cur_="${cur-}" sfx=" "
+
+ while test $# != 0; do
+ case "$1" in
+ --tags=*) tags="${1##--tags=}" ;;
+ --pfx=*) pfx="${1##--pfx=}" ;;
+ --cur=*) cur_="${1##--cur=}" ;;
+ --sfx=*) sfx="${1##--sfx=}" ;;
+ *) return 1 ;;
+ esac
+ shift
+ done
+
+ if test -r "$tags"; then
+ __gitcomp_direct "$(__git_match_ctag "$cur_" "$tags" "$pfx" "$sfx")"
+ fi
}
_git_grep ()
@@ -1306,50 +1631,34 @@ _git_grep ()
case "$cur" in
--*)
- __gitcomp "
- --cached
- --text --ignore-case --word-regexp --invert-match
- --full-name --line-number
- --extended-regexp --basic-regexp --fixed-strings
- --perl-regexp
- --threads
- --files-with-matches --name-only
- --files-without-match
- --max-depth
- --count
- --and --or --not --all-match
- "
+ __gitcomp_builtin grep
return
;;
esac
case "$cword,$prev" in
2,*|*,-*)
- if test -r tags; then
- __gitcomp_nl "$(__git_match_ctag "$cur" tags)"
- return
- fi
+ __git_complete_symbol && return
;;
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_help ()
{
case "$cur" in
--*)
- __gitcomp "--all --info --man --web"
+ __gitcomp_builtin help
return
;;
esac
- __git_compute_all_commands
- __gitcomp "$__git_all_commands $(__git_aliases)
- attributes cli core-tutorial cvs-migration
- diffcore gitk glossary hooks ignore modules
- namespaces repository-layout tutorial tutorial-2
- workflows
- "
+ if test -n "$GIT_TESTING_ALL_COMMAND_LIST"
+ then
+ __gitcomp "$GIT_TESTING_ALL_COMMAND_LIST $(__git --list-cmds=alias,list-guide) gitk"
+ else
+ __gitcomp "$(__git --list-cmds=main,nohelpers,alias,list-guide) gitk"
+ fi
}
_git_init ()
@@ -1362,7 +1671,7 @@ _git_init ()
return
;;
--*)
- __gitcomp "--quiet --bare --template= --shared --shared="
+ __gitcomp_builtin init
return
;;
esac
@@ -1372,13 +1681,7 @@ _git_ls_files ()
{
case "$cur" in
--*)
- __gitcomp "--cached --deleted --modified --others --ignored
- --stage --directory --no-empty-directory --unmerged
- --killed --exclude= --exclude-from=
- --exclude-per-directory= --exclude-standard
- --error-unmatch --with-tree= --full-name
- --abbrev --ignored --exclude-per-directory
- "
+ __gitcomp_builtin ls-files
return
;;
esac
@@ -1390,11 +1693,24 @@ _git_ls_files ()
_git_ls_remote ()
{
+ case "$cur" in
+ --*)
+ __gitcomp_builtin ls-remote
+ return
+ ;;
+ esac
__gitcomp_nl "$(__git_remotes)"
}
_git_ls_tree ()
{
+ case "$cur" in
+ --*)
+ __gitcomp_builtin ls-tree
+ return
+ ;;
+ esac
+
__git_complete_file
}
@@ -1421,18 +1737,31 @@ __git_log_shortlog_options="
--all-match --invert-grep
"
-__git_log_pretty_formats="oneline short medium full fuller email raw format:"
-__git_log_date_formats="relative iso8601 rfc2822 short local default raw"
+__git_log_pretty_formats="oneline short medium full fuller email raw format: mboxrd"
+__git_log_date_formats="relative iso8601 iso8601-strict rfc2822 short local default raw unix format:"
_git_log ()
{
__git_has_doubledash && return
+ __git_find_repo_path
- local g="$(git rev-parse --git-dir 2>/dev/null)"
local merge=""
- if [ -f "$g/MERGE_HEAD" ]; then
+ if [ -f "$__git_repo_path/MERGE_HEAD" ]; then
merge="--merge"
fi
+ case "$prev,$cur" in
+ -L,:*:*)
+ return # fall back to Bash filename completion
+ ;;
+ -L,:*)
+ __git_complete_symbol --cur="${cur#:}" --sfx=":"
+ return
+ ;;
+ -G,*|-S,*)
+ __git_complete_symbol
+ return
+ ;;
+ esac
case "$cur" in
--pretty=*|--format=*)
__gitcomp "$__git_log_pretty_formats $(__git_pretty_aliases)
@@ -1447,6 +1776,14 @@ _git_log ()
__gitcomp "full short no" "" "${cur##--decorate=}"
return
;;
+ --diff-algorithm=*)
+ __gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
+ return
+ ;;
+ --submodule=*)
+ __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
+ return
+ ;;
--*)
__gitcomp "
$__git_log_common_options
@@ -1458,6 +1795,7 @@ _git_log ()
--relative-date --date=
--pretty= --format= --oneline
--show-signature
+ --cherry-mark
--cherry-pick
--graph
--decorate --decorate=
@@ -1469,29 +1807,35 @@ _git_log ()
"
return
;;
+ -L:*:*)
+ return # fall back to Bash filename completion
+ ;;
+ -L:*)
+ __git_complete_symbol --cur="${cur#-L:}" --sfx=":"
+ return
+ ;;
+ -G*)
+ __git_complete_symbol --pfx="-G" --cur="${cur#-G}"
+ return
+ ;;
+ -S*)
+ __git_complete_symbol --pfx="-S" --cur="${cur#-S}"
+ return
+ ;;
esac
__git_complete_revlist
}
-# Common merge options shared by git-merge(1) and git-pull(1).
-__git_merge_options="
- --no-commit --no-stat --log --no-log --squash --strategy
- --commit --stat --no-squash --ff --no-ff --ff-only --edit --no-edit
- --verify-signatures --no-verify-signatures --gpg-sign
- --quiet --verbose --progress --no-progress
-"
-
_git_merge ()
{
__git_complete_strategy && return
case "$cur" in
--*)
- __gitcomp "$__git_merge_options
- --rerere-autoupdate --no-rerere-autoupdate --abort"
+ __gitcomp_builtin merge
return
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_mergetool ()
@@ -1502,7 +1846,7 @@ _git_mergetool ()
return
;;
--*)
- __gitcomp "--tool="
+ __gitcomp "--tool= --prompt --no-prompt --gui --no-gui"
return
;;
esac
@@ -1512,18 +1856,18 @@ _git_merge_base ()
{
case "$cur" in
--*)
- __gitcomp "--octopus --independent --is-ancestor --fork-point"
+ __gitcomp_builtin merge-base
return
;;
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_mv ()
{
case "$cur" in
--*)
- __gitcomp "--dry-run"
+ __gitcomp_builtin mv
return
;;
esac
@@ -1537,52 +1881,40 @@ _git_mv ()
fi
}
-_git_name_rev ()
-{
- __gitcomp "--tags --all --stdin"
-}
-
_git_notes ()
{
- local subcommands='add append copy edit list prune remove show'
+ local subcommands='add append copy edit get-ref list merge prune remove show'
local subcommand="$(__git_find_on_cmdline "$subcommands")"
case "$subcommand,$cur" in
,--*)
- __gitcomp '--ref'
+ __gitcomp_builtin notes
;;
,*)
case "$prev" in
--ref)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
;;
*)
__gitcomp "$subcommands --ref"
;;
esac
;;
- add,--reuse-message=*|append,--reuse-message=*|\
- add,--reedit-message=*|append,--reedit-message=*)
- __gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
- ;;
- add,--*|append,--*)
- __gitcomp '--file= --message= --reedit-message=
- --reuse-message='
+ *,--reuse-message=*|*,--reedit-message=*)
+ __git_complete_refs --cur="${cur#*=}"
;;
- copy,--*)
- __gitcomp '--stdin'
+ *,--*)
+ __gitcomp_builtin notes_$subcommand
;;
- prune,--*)
- __gitcomp '--dry-run --verbose'
- ;;
- prune,*)
+ prune,*|get-ref,*)
+ # this command does not take a ref, do not complete it
;;
*)
case "$prev" in
-m|-F)
;;
*)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
;;
esac
;;
@@ -1599,18 +1931,15 @@ _git_pull ()
return
;;
--*)
- __gitcomp "
- --rebase --no-rebase
- $__git_merge_options
- $__git_fetch_options
- "
+ __gitcomp_builtin pull
+
return
;;
esac
__git_complete_remote_or_refspec
}
-__git_push_recurse_submodules="check on-demand"
+__git_push_recurse_submodules="check on-demand only"
__git_complete_force_with_lease ()
{
@@ -1620,10 +1949,10 @@ __git_complete_force_with_lease ()
--*=)
;;
*:*)
- __gitcomp_nl "$(__git_refs)" "" "${cur_#*:}"
+ __git_complete_refs --cur="${cur_#*:}"
;;
*)
- __gitcomp_nl "$(__git_refs)" "" "$cur_"
+ __git_complete_refs --cur="$cur_"
;;
esac
}
@@ -1654,26 +1983,36 @@ _git_push ()
return
;;
--*)
+ __gitcomp_builtin push
+ return
+ ;;
+ esac
+ __git_complete_remote_or_refspec
+}
+
+_git_range_diff ()
+{
+ case "$cur" in
+ --*)
__gitcomp "
- --all --mirror --tags --dry-run --force --verbose
- --quiet --prune --delete --follow-tags
- --receive-pack= --repo= --set-upstream
- --force-with-lease --force-with-lease= --recurse-submodules=
+ --creation-factor= --no-dual-color
+ $__git_diff_common_options
"
return
;;
esac
- __git_complete_remote_or_refspec
+ __git_complete_revlist
}
_git_rebase ()
{
- local dir="$(__gitdir)"
- if [ -f "$dir"/rebase-merge/interactive ]; then
- __gitcomp "--continue --skip --abort --edit-todo"
+ __git_find_repo_path
+ if [ -f "$__git_repo_path"/rebase-merge/interactive ]; then
+ __gitcomp "--continue --skip --abort --quit --edit-todo --show-current-patch"
return
- elif [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
- __gitcomp "--continue --skip --abort"
+ elif [ -d "$__git_repo_path"/rebase-apply ] || \
+ [ -d "$__git_repo_path"/rebase-merge ]; then
+ __gitcomp "--continue --skip --abort --quit --show-current-patch"
return
fi
__git_complete_strategy && return
@@ -1685,7 +2024,7 @@ _git_rebase ()
--*)
__gitcomp "
--onto --merge --strategy --interactive
- --preserve-merges --stat --no-stat
+ --rebase-merges --preserve-merges --stat --no-stat
--committer-date-is-author-date --ignore-date
--ignore-whitespace --whitespace=
--autosquash --no-autosquash
@@ -1693,12 +2032,13 @@ _git_rebase ()
--autostash --no-autostash
--verify --no-verify
--keep-empty --root --force-rebase --no-ff
+ --rerere-autoupdate
--exec
"
return
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_reflog ()
@@ -1709,7 +2049,7 @@ _git_reflog ()
if [ -z "$subcommand" ]; then
__gitcomp "$subcommands"
else
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
fi
}
@@ -1720,9 +2060,7 @@ _git_send_email ()
{
case "$prev" in
--to|--cc|--bcc|--from)
- __gitcomp "
- $(git --git-dir="$(__gitdir)" send-email --dump-aliases 2>/dev/null)
- "
+ __gitcomp "$(__git send-email --dump-aliases)"
return
;;
esac
@@ -1752,22 +2090,20 @@ _git_send_email ()
return
;;
--to=*|--cc=*|--bcc=*|--from=*)
- __gitcomp "
- $(git --git-dir="$(__gitdir)" send-email --dump-aliases 2>/dev/null)
- " "" "${cur#--*=}"
+ __gitcomp "$(__git send-email --dump-aliases)" "" "${cur#--*=}"
return
;;
--*)
- __gitcomp "--annotate --bcc --cc --cc-cmd --chain-reply-to
+ __gitcomp_builtin send-email "--annotate --bcc --cc --cc-cmd --chain-reply-to
--compose --confirm= --dry-run --envelope-sender
--from --identity
--in-reply-to --no-chain-reply-to --no-signed-off-by-cc
- --no-suppress-from --no-thread --quiet
+ --no-suppress-from --no-thread --quiet --reply-to
--signed-off-by-cc --smtp-pass --smtp-server
--smtp-server-port --smtp-encryption= --smtp-user
--subject --suppress-cc= --suppress-from --thread --to
--validate --no-validate
- $__git_format_patch_options"
+ $__git_format_patch_extra_options"
return
;;
esac
@@ -1779,6 +2115,90 @@ _git_stage ()
_git_add
}
+_git_status ()
+{
+ local complete_opt
+ local untracked_state
+
+ case "$cur" in
+ --ignore-submodules=*)
+ __gitcomp "none untracked dirty all" "" "${cur##--ignore-submodules=}"
+ return
+ ;;
+ --untracked-files=*)
+ __gitcomp "$__git_untracked_file_modes" "" "${cur##--untracked-files=}"
+ return
+ ;;
+ --column=*)
+ __gitcomp "
+ always never auto column row plain dense nodense
+ " "" "${cur##--column=}"
+ return
+ ;;
+ --*)
+ __gitcomp_builtin status
+ return
+ ;;
+ esac
+
+ untracked_state="$(__git_get_option_value "-u" "--untracked-files=" \
+ "$__git_untracked_file_modes" "status.showUntrackedFiles")"
+
+ case "$untracked_state" in
+ no)
+ # --ignored option does not matter
+ complete_opt=
+ ;;
+ all|normal|*)
+ complete_opt="--cached --directory --no-empty-directory --others"
+
+ if [ -n "$(__git_find_on_cmdline "--ignored")" ]; then
+ complete_opt="$complete_opt --ignored --exclude=*"
+ fi
+ ;;
+ esac
+
+ __git_complete_index_file "$complete_opt"
+}
+
+_git_switch ()
+{
+ case "$cur" in
+ --conflict=*)
+ __gitcomp "diff3 merge" "" "${cur##--conflict=}"
+ ;;
+ --*)
+ __gitcomp_builtin switch
+ ;;
+ *)
+ # check if --track, --no-track, or --no-guess was specified
+ # if so, disable DWIM mode
+ local track_opt="--track" only_local_ref=n
+ if [ "$GIT_COMPLETION_CHECKOUT_NO_GUESS" = "1" ] ||
+ [ -n "$(__git_find_on_cmdline "--track --no-track --no-guess")" ]; then
+ track_opt=''
+ fi
+ # explicit --guess enables DWIM mode regardless of
+ # $GIT_COMPLETION_CHECKOUT_NO_GUESS
+ if [ -n "$(__git_find_on_cmdline "--guess")" ]; then
+ track_opt='--track'
+ fi
+ if [ -z "$(__git_find_on_cmdline "-d --detach")" ]; then
+ only_local_ref=y
+ else
+ # --guess --detach is invalid combination, no
+ # dwim will be done when --detach is specified
+ track_opt=
+ fi
+ if [ $only_local_ref = y -a -z "$track_opt" ]; then
+ __gitcomp_direct "$(__git_heads "" "$cur" " ")"
+ else
+ __git_complete_refs $track_opt
+ fi
+ ;;
+ esac
+}
+
__git_config_get_set_variables ()
{
local prevword word config_file= c=$cword
@@ -1798,22 +2218,37 @@ __git_config_get_set_variables ()
c=$((--c))
done
- git --git-dir="$(__gitdir)" config $config_file --name-only --list 2>/dev/null
+ __git config $config_file --name-only --list
+}
+
+__git_config_vars=
+__git_compute_config_vars ()
+{
+ test -n "$__git_config_vars" ||
+ __git_config_vars="$(git help --config-for-completion | sort | uniq)"
}
_git_config ()
{
- case "$prev" in
+ local varname
+
+ if [ "${BASH_VERSINFO[0]:-0}" -ge 4 ]; then
+ varname="${prev,,}"
+ else
+ varname="$(echo "$prev" |tr A-Z a-z)"
+ fi
+
+ case "$varname" in
branch.*.remote|branch.*.pushremote)
__gitcomp_nl "$(__git_remotes)"
return
;;
branch.*.merge)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
return
;;
branch.*.rebase)
- __gitcomp "false true preserve interactive"
+ __gitcomp "false true merges preserve interactive"
return
;;
remote.pushdefault)
@@ -1833,9 +2268,8 @@ _git_config ()
remote.*.push)
local remote="${prev#remote.}"
remote="${remote%.push}"
- __gitcomp_nl "$(git --git-dir="$(__gitdir)" \
- for-each-ref --format='%(refname):%(refname)' \
- refs/heads)"
+ __gitcomp_nl "$(__git for-each-ref \
+ --format='%(refname):%(refname)' refs/heads)"
return
;;
pull.twohead|pull.octopus)
@@ -1860,7 +2294,7 @@ _git_config ()
return
;;
diff.submodule)
- __gitcomp "log short"
+ __gitcomp "$__git_diff_submodule_formats"
return
;;
help.format)
@@ -1871,7 +2305,7 @@ _git_config ()
__gitcomp "$__git_log_date_formats"
return
;;
- sendemail.aliasesfiletype)
+ sendemail.aliasfiletype)
__gitcomp "mutt mailrc pine elm gnus"
return
;;
@@ -1897,32 +2331,25 @@ _git_config ()
esac
case "$cur" in
--*)
- __gitcomp "
- --system --global --local --file=
- --list --replace-all
- --get --get-all --get-regexp
- --add --unset --unset-all
- --remove-section --rename-section
- --name-only
- "
+ __gitcomp_builtin config
return
;;
branch.*.*)
local pfx="${cur%.*}." cur_="${cur##*.}"
- __gitcomp "remote pushremote merge mergeoptions rebase" "$pfx" "$cur_"
+ __gitcomp "remote pushRemote merge mergeOptions rebase" "$pfx" "$cur_"
return
;;
branch.*)
local pfx="${cur%.*}." cur_="${cur#*.}"
- __gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
- __gitcomp_nl_append $'autosetupmerge\nautosetuprebase\n' "$pfx" "$cur_"
+ __gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")"
+ __gitcomp_nl_append $'autoSetupMerge\nautoSetupRebase\n' "$pfx" "$cur_"
return
;;
guitool.*.*)
local pfx="${cur%.*}." cur_="${cur##*.}"
__gitcomp "
- argprompt cmd confirm needsfile noconsole norescan
- prompt revprompt revunmerged title
+ argPrompt cmd confirm needsFile noConsole noRescan
+ prompt revPrompt revUnmerged title
" "$pfx" "$cur_"
return
;;
@@ -1951,14 +2378,14 @@ _git_config ()
local pfx="${cur%.*}." cur_="${cur##*.}"
__gitcomp "
url proxy fetch push mirror skipDefaultUpdate
- receivepack uploadpack tagopt pushurl
+ receivepack uploadpack tagOpt pushurl
" "$pfx" "$cur_"
return
;;
remote.*)
local pfx="${cur%.*}." cur_="${cur#*.}"
__gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
- __gitcomp_nl_append "pushdefault" "$pfx" "$cur_"
+ __gitcomp_nl_append "pushDefault" "$pfx" "$cur_"
return
;;
url.*.*)
@@ -1966,324 +2393,95 @@ _git_config ()
__gitcomp "insteadOf pushInsteadOf" "$pfx" "$cur_"
return
;;
+ *.*)
+ __git_compute_config_vars
+ __gitcomp "$__git_config_vars"
+ ;;
+ *)
+ __git_compute_config_vars
+ __gitcomp "$(echo "$__git_config_vars" | sed 's/\.[^ ]*/./g')"
esac
- __gitcomp "
- add.ignoreErrors
- advice.commitBeforeMerge
- advice.detachedHead
- advice.implicitIdentity
- advice.pushNonFastForward
- advice.resolveConflict
- advice.statusHints
- alias.
- am.keepcr
- apply.ignorewhitespace
- apply.whitespace
- branch.autosetupmerge
- branch.autosetuprebase
- browser.
- clean.requireForce
- color.branch
- color.branch.current
- color.branch.local
- color.branch.plain
- color.branch.remote
- color.decorate.HEAD
- color.decorate.branch
- color.decorate.remoteBranch
- color.decorate.stash
- color.decorate.tag
- color.diff
- color.diff.commit
- color.diff.frag
- color.diff.func
- color.diff.meta
- color.diff.new
- color.diff.old
- color.diff.plain
- color.diff.whitespace
- color.grep
- color.grep.context
- color.grep.filename
- color.grep.function
- color.grep.linenumber
- color.grep.match
- color.grep.selected
- color.grep.separator
- color.interactive
- color.interactive.error
- color.interactive.header
- color.interactive.help
- color.interactive.prompt
- color.pager
- color.showbranch
- color.status
- color.status.added
- color.status.changed
- color.status.header
- color.status.nobranch
- color.status.unmerged
- color.status.untracked
- color.status.updated
- color.ui
- commit.status
- commit.template
- core.abbrev
- core.askpass
- core.attributesfile
- core.autocrlf
- core.bare
- core.bigFileThreshold
- core.compression
- core.createObject
- core.deltaBaseCacheLimit
- core.editor
- core.eol
- core.excludesfile
- core.fileMode
- core.fsyncobjectfiles
- core.gitProxy
- core.ignoreStat
- core.ignorecase
- core.logAllRefUpdates
- core.loosecompression
- core.notesRef
- core.packedGitLimit
- core.packedGitWindowSize
- core.pager
- core.preferSymlinkRefs
- core.preloadindex
- core.quotepath
- core.repositoryFormatVersion
- core.safecrlf
- core.sharedRepository
- core.sparseCheckout
- core.symlinks
- core.trustctime
- core.untrackedCache
- core.warnAmbiguousRefs
- core.whitespace
- core.worktree
- diff.autorefreshindex
- diff.external
- diff.ignoreSubmodules
- diff.mnemonicprefix
- diff.noprefix
- diff.renameLimit
- diff.renames
- diff.statGraphWidth
- diff.submodule
- diff.suppressBlankEmpty
- diff.tool
- diff.wordRegex
- diff.algorithm
- difftool.
- difftool.prompt
- fetch.recurseSubmodules
- fetch.unpackLimit
- format.attach
- format.cc
- format.coverLetter
- format.headers
- format.numbered
- format.pretty
- format.signature
- format.signoff
- format.subjectprefix
- format.suffix
- format.thread
- format.to
- gc.
- gc.aggressiveWindow
- gc.auto
- gc.autopacklimit
- gc.packrefs
- gc.pruneexpire
- gc.reflogexpire
- gc.reflogexpireunreachable
- gc.rerereresolved
- gc.rerereunresolved
- gitcvs.allbinary
- gitcvs.commitmsgannotation
- gitcvs.dbTableNamePrefix
- gitcvs.dbdriver
- gitcvs.dbname
- gitcvs.dbpass
- gitcvs.dbuser
- gitcvs.enabled
- gitcvs.logfile
- gitcvs.usecrlfattr
- guitool.
- gui.blamehistoryctx
- gui.commitmsgwidth
- gui.copyblamethreshold
- gui.diffcontext
- gui.encoding
- gui.fastcopyblame
- gui.matchtrackingbranch
- gui.newbranchtemplate
- gui.pruneduringfetch
- gui.spellingdictionary
- gui.trustmtime
- help.autocorrect
- help.browser
- help.format
- http.lowSpeedLimit
- http.lowSpeedTime
- http.maxRequests
- http.minSessions
- http.noEPSV
- http.postBuffer
- http.proxy
- http.sslCipherList
- http.sslVersion
- http.sslCAInfo
- http.sslCAPath
- http.sslCert
- http.sslCertPasswordProtected
- http.sslKey
- http.sslVerify
- http.useragent
- i18n.commitEncoding
- i18n.logOutputEncoding
- imap.authMethod
- imap.folder
- imap.host
- imap.pass
- imap.port
- imap.preformattedHTML
- imap.sslverify
- imap.tunnel
- imap.user
- init.templatedir
- instaweb.browser
- instaweb.httpd
- instaweb.local
- instaweb.modulepath
- instaweb.port
- interactive.singlekey
- log.date
- log.decorate
- log.showroot
- mailmap.file
- man.
- man.viewer
- merge.
- merge.conflictstyle
- merge.log
- merge.renameLimit
- merge.renormalize
- merge.stat
- merge.tool
- merge.verbosity
- mergetool.
- mergetool.keepBackup
- mergetool.keepTemporaries
- mergetool.prompt
- notes.displayRef
- notes.rewrite.
- notes.rewrite.amend
- notes.rewrite.rebase
- notes.rewriteMode
- notes.rewriteRef
- pack.compression
- pack.deltaCacheLimit
- pack.deltaCacheSize
- pack.depth
- pack.indexVersion
- pack.packSizeLimit
- pack.threads
- pack.window
- pack.windowMemory
- pager.
- pretty.
- pull.octopus
- pull.twohead
- push.default
- push.followTags
- rebase.autosquash
- rebase.stat
- receive.autogc
- receive.denyCurrentBranch
- receive.denyDeleteCurrent
- receive.denyDeletes
- receive.denyNonFastForwards
- receive.fsckObjects
- receive.unpackLimit
- receive.updateserverinfo
- remote.pushdefault
- remotes.
- repack.usedeltabaseoffset
- rerere.autoupdate
- rerere.enabled
- sendemail.
- sendemail.aliasesfile
- sendemail.aliasfiletype
- sendemail.bcc
- sendemail.cc
- sendemail.cccmd
- sendemail.chainreplyto
- sendemail.confirm
- sendemail.envelopesender
- sendemail.from
- sendemail.identity
- sendemail.multiedit
- sendemail.signedoffbycc
- sendemail.smtpdomain
- sendemail.smtpencryption
- sendemail.smtppass
- sendemail.smtpserver
- sendemail.smtpserveroption
- sendemail.smtpserverport
- sendemail.smtpuser
- sendemail.suppresscc
- sendemail.suppressfrom
- sendemail.thread
- sendemail.to
- sendemail.validate
- showbranch.default
- status.relativePaths
- status.showUntrackedFiles
- status.submodulesummary
- submodule.
- tar.umask
- transfer.unpackLimit
- url.
- user.email
- user.name
- user.signingkey
- web.browser
- branch. remote.
- "
}
_git_remote ()
{
- local subcommands="add rename remove set-head set-branches set-url show prune update"
+ local subcommands="
+ add rename remove set-head set-branches
+ get-url set-url show prune update
+ "
local subcommand="$(__git_find_on_cmdline "$subcommands")"
if [ -z "$subcommand" ]; then
- __gitcomp "$subcommands"
+ case "$cur" in
+ --*)
+ __gitcomp_builtin remote
+ ;;
+ *)
+ __gitcomp "$subcommands"
+ ;;
+ esac
return
fi
- case "$subcommand" in
- rename|remove|set-url|show|prune)
- __gitcomp_nl "$(__git_remotes)"
+ case "$subcommand,$cur" in
+ add,--*)
+ __gitcomp_builtin remote_add
+ ;;
+ add,*)
+ ;;
+ set-head,--*)
+ __gitcomp_builtin remote_set-head
;;
- set-head|set-branches)
+ set-branches,--*)
+ __gitcomp_builtin remote_set-branches
+ ;;
+ set-head,*|set-branches,*)
__git_complete_remote_or_refspec
;;
- update)
- __gitcomp "$(__git_get_config_variables "remotes")"
+ update,--*)
+ __gitcomp_builtin remote_update
+ ;;
+ update,*)
+ __gitcomp "$(__git_remotes) $(__git_get_config_variables "remotes")"
+ ;;
+ set-url,--*)
+ __gitcomp_builtin remote_set-url
+ ;;
+ get-url,--*)
+ __gitcomp_builtin remote_get-url
+ ;;
+ prune,--*)
+ __gitcomp_builtin remote_prune
;;
*)
+ __gitcomp_nl "$(__git_remotes)"
;;
esac
}
_git_replace ()
{
- __gitcomp_nl "$(__git_refs)"
+ case "$cur" in
+ --format=*)
+ __gitcomp "short medium long" "" "${cur##--format=}"
+ return
+ ;;
+ --*)
+ __gitcomp_builtin replace
+ return
+ ;;
+ esac
+ __git_complete_refs
+}
+
+_git_rerere ()
+{
+ local subcommands="clear forget diff remaining status gc"
+ local subcommand="$(__git_find_on_cmdline "$subcommands")"
+ if test -z "$subcommand"
+ then
+ __gitcomp "$subcommands"
+ return
+ fi
}
_git_reset ()
@@ -2292,34 +2490,53 @@ _git_reset ()
case "$cur" in
--*)
- __gitcomp "--merge --mixed --hard --soft --patch"
+ __gitcomp_builtin reset
return
;;
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
+_git_restore ()
+{
+ case "$cur" in
+ --conflict=*)
+ __gitcomp "diff3 merge" "" "${cur##--conflict=}"
+ ;;
+ --source=*)
+ __git_complete_refs --cur="${cur##--source=}"
+ ;;
+ --*)
+ __gitcomp_builtin restore
+ ;;
+ esac
+}
+
+__git_revert_inprogress_options="--continue --quit --abort"
+
_git_revert ()
{
- local dir="$(__gitdir)"
- if [ -f "$dir"/REVERT_HEAD ]; then
- __gitcomp "--continue --quit --abort"
+ __git_find_repo_path
+ if [ -f "$__git_repo_path"/REVERT_HEAD ]; then
+ __gitcomp "$__git_revert_inprogress_options"
return
fi
+ __git_complete_strategy && return
case "$cur" in
--*)
- __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
+ __gitcomp_builtin revert "" \
+ "$__git_revert_inprogress_options"
return
;;
esac
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
}
_git_rm ()
{
case "$cur" in
--*)
- __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
+ __gitcomp_builtin rm
return
;;
esac
@@ -2336,7 +2553,7 @@ _git_shortlog ()
__gitcomp "
$__git_log_common_options
$__git_log_shortlog_options
- --numbered --summary
+ --numbered --summary --email
"
return
;;
@@ -2358,6 +2575,10 @@ _git_show ()
__gitcomp "$__git_diff_algorithms" "" "${cur##--diff-algorithm=}"
return
;;
+ --submodule=*)
+ __gitcomp "$__git_diff_submodule_formats" "" "${cur##--submodule=}"
+ return
+ ;;
--*)
__gitcomp "--pretty= --format= --abbrev-commit --oneline
--show-signature
@@ -2373,12 +2594,7 @@ _git_show_branch ()
{
case "$cur" in
--*)
- __gitcomp "
- --all --remotes --topo-order --date-order --current --more=
- --list --independent --merge-base --no-name
- --color --no-color
- --sha1-name --sparse --topics --reflog
- "
+ __gitcomp_builtin show-branch
return
;;
esac
@@ -2388,13 +2604,21 @@ _git_show_branch ()
_git_stash ()
{
local save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'
- local subcommands='save list show apply clear drop pop create branch'
- local subcommand="$(__git_find_on_cmdline "$subcommands")"
+ local subcommands='push list show apply clear drop pop create branch'
+ local subcommand="$(__git_find_on_cmdline "$subcommands save")"
+ if [ -n "$(__git_find_on_cmdline "-p")" ]; then
+ subcommand="push"
+ fi
if [ -z "$subcommand" ]; then
case "$cur" in
--*)
__gitcomp "$save_opts"
;;
+ sa*)
+ if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
+ __gitcomp "save"
+ fi
+ ;;
*)
if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
__gitcomp "$subcommands"
@@ -2403,6 +2627,9 @@ _git_stash ()
esac
else
case "$subcommand,$cur" in
+ push,--*)
+ __gitcomp "$save_opts --message"
+ ;;
save,--*)
__gitcomp "$save_opts"
;;
@@ -2412,18 +2639,21 @@ _git_stash ()
drop,--*)
__gitcomp "--quiet"
;;
+ list,--*)
+ __gitcomp "--name-status --oneline --patch-with-stat"
+ ;;
show,--*|branch,--*)
;;
branch,*)
if [ $cword -eq 3 ]; then
- __gitcomp_nl "$(__git_refs)";
+ __git_complete_refs
else
- __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
+ __gitcomp_nl "$(__git stash list \
| sed -n -e 's/:.*//p')"
fi
;;
show,*|apply,*|drop,*|pop,*)
- __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
+ __gitcomp_nl "$(__git stash list \
| sed -n -e 's/:.*//p')"
;;
*)
@@ -2436,11 +2666,12 @@ _git_submodule ()
{
__git_has_doubledash && return
- local subcommands="add status init deinit update summary foreach sync"
- if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then
+ local subcommands="add status init deinit update set-branch summary foreach sync absorbgitdirs"
+ local subcommand="$(__git_find_on_cmdline "$subcommands")"
+ if [ -z "$subcommand" ]; then
case "$cur" in
--*)
- __gitcomp "--quiet --cached"
+ __gitcomp "--quiet"
;;
*)
__gitcomp "$subcommands"
@@ -2448,6 +2679,36 @@ _git_submodule ()
esac
return
fi
+
+ case "$subcommand,$cur" in
+ add,--*)
+ __gitcomp "--branch --force --name --reference --depth"
+ ;;
+ status,--*)
+ __gitcomp "--cached --recursive"
+ ;;
+ deinit,--*)
+ __gitcomp "--force --all"
+ ;;
+ update,--*)
+ __gitcomp "
+ --init --remote --no-fetch
+ --recommend-shallow --no-recommend-shallow
+ --force --rebase --merge --reference --depth --recursive --jobs
+ "
+ ;;
+ set-branch,--*)
+ __gitcomp "--default --branch"
+ ;;
+ summary,--*)
+ __gitcomp "--cached --files --summary-limit"
+ ;;
+ foreach,--*|sync,--*)
+ __gitcomp "--recursive"
+ ;;
+ *)
+ ;;
+ esac
}
_git_svn ()
@@ -2468,14 +2729,14 @@ _git_svn ()
--no-metadata --use-svm-props --use-svnsync-props
--log-window-size= --no-checkout --quiet
--repack-flags --use-log-author --localtime
+ --add-author-from
--ignore-paths= --include-paths= $remote_opts
"
local init_opts="
--template= --shared= --trunk= --tags=
--branches= --stdlayout --minimize-url
--no-metadata --use-svm-props --use-svnsync-props
- --rewrite-root= --prefix= --use-log-author
- --add-author-from $remote_opts
+ --rewrite-root= --prefix= $remote_opts
"
local cmt_opts="
--edit --rmdir --find-copies-harder --copy-similarity=
@@ -2554,8 +2815,8 @@ _git_tag ()
while [ $c -lt $cword ]; do
i="${words[c]}"
case "$i" in
- -d|-v)
- __gitcomp_nl "$(__git_tags)"
+ -d|--delete|-v|--verify)
+ __gitcomp_direct "$(__git_tags "" "$cur" " ")"
return
;;
-f)
@@ -2570,21 +2831,17 @@ _git_tag ()
;;
-*|tag)
if [ $f = 1 ]; then
- __gitcomp_nl "$(__git_tags)"
+ __gitcomp_direct "$(__git_tags "" "$cur" " ")"
fi
;;
*)
- __gitcomp_nl "$(__git_refs)"
+ __git_complete_refs
;;
esac
case "$cur" in
--*)
- __gitcomp "
- --list --delete --verify --annotate --message --file
- --sign --cleanup --local-user --force --column --sort
- --contains --points-at
- "
+ __gitcomp_builtin tag
;;
esac
}
@@ -2594,9 +2851,85 @@ _git_whatchanged ()
_git_log
}
+_git_worktree ()
+{
+ local subcommands="add list lock move prune remove unlock"
+ local subcommand="$(__git_find_on_cmdline "$subcommands")"
+ if [ -z "$subcommand" ]; then
+ __gitcomp "$subcommands"
+ else
+ case "$subcommand,$cur" in
+ add,--*)
+ __gitcomp_builtin worktree_add
+ ;;
+ list,--*)
+ __gitcomp_builtin worktree_list
+ ;;
+ lock,--*)
+ __gitcomp_builtin worktree_lock
+ ;;
+ prune,--*)
+ __gitcomp_builtin worktree_prune
+ ;;
+ remove,--*)
+ __gitcomp "--force"
+ ;;
+ *)
+ ;;
+ esac
+ fi
+}
+
+__git_complete_common () {
+ local command="$1"
+
+ case "$cur" in
+ --*)
+ __gitcomp_builtin "$command"
+ ;;
+ esac
+}
+
+__git_cmds_with_parseopt_helper=
+__git_support_parseopt_helper () {
+ test -n "$__git_cmds_with_parseopt_helper" ||
+ __git_cmds_with_parseopt_helper="$(__git --list-cmds=parseopt)"
+
+ case " $__git_cmds_with_parseopt_helper " in
+ *" $1 "*)
+ return 0
+ ;;
+ *)
+ return 1
+ ;;
+ esac
+}
+
+__git_complete_command () {
+ local command="$1"
+ local completion_func="_git_${command//-/_}"
+ if ! declare -f $completion_func >/dev/null 2>/dev/null &&
+ declare -f _completion_loader >/dev/null 2>/dev/null
+ then
+ _completion_loader "git-$command"
+ fi
+ if declare -f $completion_func >/dev/null 2>/dev/null
+ then
+ $completion_func
+ return 0
+ elif __git_support_parseopt_helper "$command"
+ then
+ __git_complete_common "$command"
+ return 0
+ else
+ return 1
+ fi
+}
+
__git_main ()
{
- local i c=1 command __git_dir
+ local i c=1 command __git_dir __git_repo_path
+ local __git_C_args C_args_count=0
while [ $c -lt $cword ]; do
i="${words[c]}"
@@ -2606,6 +2939,10 @@ __git_main ()
--bare) __git_dir="." ;;
--help) command="help"; break ;;
-c|--work-tree|--namespace) ((c++)) ;;
+ -C) __git_C_args[C_args_count++]=-C
+ ((c++))
+ __git_C_args[C_args_count++]="${words[c]}"
+ ;;
-*) ;;
*) command="$i"; break ;;
esac
@@ -2613,6 +2950,17 @@ __git_main ()
done
if [ -z "$command" ]; then
+ case "$prev" in
+ --git-dir|-C|--work-tree)
+ # these need a path argument, let's fall back to
+ # Bash filename completion
+ return
+ ;;
+ -c|--namespace)
+ # we don't support completing these options' arguments
+ return
+ ;;
+ esac
case "$cur" in
--*) __gitcomp "
--paginate
@@ -2631,20 +2979,24 @@ __git_main ()
--help
"
;;
- *) __git_compute_porcelain_commands
- __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
+ *)
+ if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
+ then
+ __gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
+ else
+ __gitcomp "$(__git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)"
+ fi
+ ;;
esac
return
fi
- local completion_func="_git_${command//-/_}"
- declare -f $completion_func >/dev/null && $completion_func && return
+ __git_complete_command "$command" && return
local expansion=$(__git_aliased_command "$command")
if [ -n "$expansion" ]; then
words[1]=$expansion
- completion_func="_git_${expansion//-/_}"
- declare -f $completion_func >/dev/null && $completion_func
+ __git_complete_command "$expansion"
fi
}
@@ -2652,9 +3004,11 @@ __gitk_main ()
{
__git_has_doubledash && return
- local g="$(__gitdir)"
+ local __git_repo_path
+ __git_find_repo_path
+
local merge=""
- if [ -f "$g/MERGE_HEAD" ]; then
+ if [ -f "$__git_repo_path/MERGE_HEAD" ]; then
merge="--merge"
fi
case "$cur" in
@@ -2670,7 +3024,10 @@ __gitk_main ()
__git_complete_revlist
}
-if [[ -n ${ZSH_VERSION-} ]]; then
+if [[ -n ${ZSH_VERSION-} ]] &&
+ # Don't define these functions when sourced from 'git-completion.zsh',
+ # it has its own implementations.
+ [[ -z ${GIT_SOURCING_ZSH_COMPLETION-} ]]; then
echo "WARNING: this script is deprecated, please see git-completion.zsh" 1>&2
autoload -U +X compinit && compinit
@@ -2701,6 +3058,15 @@ if [[ -n ${ZSH_VERSION-} ]]; then
esac
}
+ __gitcomp_direct ()
+ {
+ emulate -L zsh
+
+ local IFS=$'\n'
+ compset -P '*[=:]'
+ compadd -Q -- ${=1} && _ret=0
+ }
+
__gitcomp_nl ()
{
emulate -L zsh
@@ -2710,13 +3076,22 @@ if [[ -n ${ZSH_VERSION-} ]]; then
compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
}
+ __gitcomp_file_direct ()
+ {
+ emulate -L zsh
+
+ local IFS=$'\n'
+ compset -P '*[=:]'
+ compadd -f -- ${=1} && _ret=0
+ }
+
__gitcomp_file ()
{
emulate -L zsh
local IFS=$'\n'
compset -P '*[=:]'
- compadd -Q -p "${2-}" -f -- ${=1} && _ret=0
+ compadd -p "${2-}" -f -- ${=1} && _ret=0
}
_git ()
diff --git a/plugins/gitfast/git-prompt.sh b/plugins/gitfast/git-prompt.sh
index 0da14eee9..f7009b063 100644
--- a/plugins/gitfast/git-prompt.sh
+++ b/plugins/gitfast/git-prompt.sh
@@ -82,6 +82,7 @@
# contains relative to newer annotated tag (v1.6.3.2~35)
# branch relative to newer tag or branch (master~4)
# describe relative to older annotated tag (v1.6.3.1-13-gdd42c2f)
+# tag relative to any older tag (v1.6.3.1-13-gdd42c2f)
# default exactly matching tag
#
# If you would like a colored hint about the current dirty state, set
@@ -218,7 +219,7 @@ __git_ps1_show_upstream ()
if [[ -n "$count" && -n "$name" ]]; then
__git_ps1_upstream_name=$(git rev-parse \
--abbrev-ref "$upstream" 2>/dev/null)
- if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
+ if [ "$pcmode" = yes ] && [ "$ps1_expanded" = yes ]; then
p="$p \${__git_ps1_upstream_name}"
else
p="$p ${__git_ps1_upstream_name}"
@@ -236,7 +237,7 @@ __git_ps1_show_upstream ()
# to build a gitstring.
__git_ps1_colorize_gitstring ()
{
- if [[ -n ${ZSH_VERSION-} ]]; then
+ if [[ -n "${ZSH_VERSION-}" ]]; then
local c_red='%F{red}'
local c_green='%F{green}'
local c_lblue='%F{blue}'
@@ -254,7 +255,7 @@ __git_ps1_colorize_gitstring ()
local flags_color="$c_lblue"
local branch_color=""
- if [ $detached = no ]; then
+ if [ "$detached" = no ]; then
branch_color="$ok_color"
else
branch_color="$bad_color"
@@ -277,11 +278,12 @@ __git_ps1_colorize_gitstring ()
r="$c_clear$r"
}
+# Helper function to read the first line of a file into a variable.
+# __git_eread requires 2 arguments, the file path and the name of the
+# variable, in that order.
__git_eread ()
{
- local f="$1"
- shift
- test -r "$f" && read "$@" <"$f"
+ test -r "$1" && IFS=$'\r\n' read "$2" <"$1"
}
# __git_ps1 accepts 0 or 1 arguments (i.e., format string)
@@ -355,8 +357,8 @@ __git_ps1 ()
# incorrect.)
#
local ps1_expanded=yes
- [ -z "$ZSH_VERSION" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
- [ -z "$BASH_VERSION" ] || shopt -q promptvars || ps1_expanded=no
+ [ -z "${ZSH_VERSION-}" ] || [[ -o PROMPT_SUBST ]] || ps1_expanded=no
+ [ -z "${BASH_VERSION-}" ] || shopt -q promptvars || ps1_expanded=no
local repo_info rev_parse_exit_code
repo_info="$(git rev-parse --git-dir --is-inside-git-dir \
@@ -368,7 +370,7 @@ __git_ps1 ()
return $exit
fi
- local short_sha
+ local short_sha=""
if [ "$rev_parse_exit_code" = "0" ]; then
short_sha="${repo_info##*$'\n'}"
repo_info="${repo_info%$'\n'*}"
@@ -443,6 +445,8 @@ __git_ps1 ()
git describe --contains HEAD ;;
(branch)
git describe --contains --all HEAD ;;
+ (tag)
+ git describe --tags HEAD ;;
(describe)
git describe HEAD ;;
(* | default)
@@ -504,13 +508,13 @@ __git_ps1 ()
# NO color option unless in PROMPT_COMMAND mode or it's Zsh
if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
- if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then
+ if [ "$pcmode" = yes ] || [ -n "${ZSH_VERSION-}" ]; then
__git_ps1_colorize_gitstring
fi
fi
b=${b##refs/heads/}
- if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
+ if [ "$pcmode" = yes ] && [ "$ps1_expanded" = yes ]; then
__git_ps1_branch_name=$b
b="\${__git_ps1_branch_name}"
fi
@@ -518,7 +522,7 @@ __git_ps1 ()
local f="$w$i$s$u"
local gitstring="$c$b${f:+$z$f}$r$p"
- if [ $pcmode = yes ]; then
+ if [ "$pcmode" = yes ]; then
if [ "${__git_printf_supports_v-}" != yes ]; then
gitstring=$(printf -- "$printf_format" "$gitstring")
else
diff --git a/plugins/gitfast/gitfast.plugin.zsh b/plugins/gitfast/gitfast.plugin.zsh
index dba1b1315..7b6b67e92 100644
--- a/plugins/gitfast/gitfast.plugin.zsh
+++ b/plugins/gitfast/gitfast.plugin.zsh
@@ -1,6 +1,4 @@
-dir=$(dirname $0)
-source $dir/../git/git.plugin.zsh
-source $dir/git-prompt.sh
+source "${0:A:h}/git-prompt.sh"
function git_prompt_info() {
dirty="$(parse_git_dirty)"
diff --git a/plugins/gitfast/update b/plugins/gitfast/update
new file mode 100755
index 000000000..05054245f
--- /dev/null
+++ b/plugins/gitfast/update
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+url="https://git.kernel.org/pub/scm/git/git.git/plain/contrib/completion"
+version="2.16.0"
+
+curl -s -o _git "${url}/git-completion.zsh?h=v${version}" &&
+curl -s -o git-completion.bash "${url}/git-completion.bash?h=v${version}" &&
+curl -s -o git-prompt.sh "${url}/git-prompt.sh?h=v${version}" &&
+git apply updates.patch
diff --git a/plugins/gitfast/updates.patch b/plugins/gitfast/updates.patch
new file mode 100644
index 000000000..28a31f859
--- /dev/null
+++ b/plugins/gitfast/updates.patch
@@ -0,0 +1,56 @@
+diff --git b/plugins/gitfast/_git a/plugins/gitfast/_git
+index e2554130..a2e3bef5 100644
+--- b/plugins/gitfast/_git
++++ a/plugins/gitfast/_git
+@@ -30,7 +30,7 @@ if [ -z "$script" ]; then
+ local -a locations
+ local e
+ locations=(
+- $(dirname ${funcsourcetrace[1]%:*})/git-completion.bash
++ "$(dirname ${funcsourcetrace[1]%:*})/git-completion.bash"
+ '/etc/bash_completion.d/git' # fedora, old debian
+ '/usr/share/bash-completion/completions/git' # arch, ubuntu, new debian
+ '/usr/share/bash-completion/git' # gentoo
+@@ -214,8 +214,10 @@ _git ()
+
+ if (( $+functions[__${service}_zsh_main] )); then
+ __${service}_zsh_main
+- else
++ elif (( $+functions[__${service}_main] )); then
+ emulate ksh -c __${service}_main
++ elif (( $+functions[_${service}] )); then
++ emulate ksh -c _${service}
+ fi
+
+ let _ret && _default && _ret=0
+diff --git b/plugins/gitfast/git-completion.bash a/plugins/gitfast/git-completion.bash
+index 9c8f7380..14012cab 100644
+--- b/plugins/gitfast/git-completion.bash
++++ a/plugins/gitfast/git-completion.bash
+@@ -2915,6 +2915,6 @@ __git_complete gitk __gitk_main
+ # when the user has tab-completed the executable name and consequently
+ # included the '.exe' suffix.
+ #
+-if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
++if [[ "$OSTYPE" = cygwin* ]]; then
+ __git_complete git.exe __git_main
+ fi
+diff --git b/plugins/gitfast/git-prompt.sh a/plugins/gitfast/git-prompt.sh
+index 97eacd78..c1de34eb 100644
+--- b/plugins/gitfast/git-prompt.sh
++++ a/plugins/gitfast/git-prompt.sh
+@@ -502,9 +502,11 @@ __git_ps1 ()
+
+ local z="${GIT_PS1_STATESEPARATOR-" "}"
+
+- # NO color option unless in PROMPT_COMMAND mode
+- if [ $pcmode = yes ] && [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
+- __git_ps1_colorize_gitstring
++ # NO color option unless in PROMPT_COMMAND mode or it's Zsh
++ if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
++ if [ $pcmode = yes ] || [ -n "${ZSH_VERSION-}" ]; then
++ __git_ps1_colorize_gitstring
++ fi
+ fi
+
+ b=${b##refs/heads/}