diff options
Diffstat (limited to 'plugins/gitfast')
| -rw-r--r-- | plugins/gitfast/_git | 19 | ||||
| -rw-r--r-- | plugins/gitfast/git-completion.bash | 1351 | 
2 files changed, 604 insertions, 766 deletions
| diff --git a/plugins/gitfast/_git b/plugins/gitfast/_git index 78a6dbb3d..886bf95d1 100644 --- a/plugins/gitfast/_git +++ b/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 @@ -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 ()  { @@ -93,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 () @@ -223,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 b6ff5dc08..e087c4bf0 100644 --- a/plugins/gitfast/git-completion.bash +++ b/plugins/gitfast/git-completion.bash @@ -29,13 +29,16 @@  # 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 -#     completion (e.g., completing "foo" when "origin/foo" exists). +#     and git-switch completion (e.g., completing "foo" when "origin/foo" +#     exists).  case "$COMP_WORDBREAKS" in  *:*) : great ;; @@ -92,6 +95,70 @@ __git ()  		${__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+ @@ -264,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 @@ -280,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 () @@ -303,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: @@ -322,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 @@ -332,10 +483,12 @@ __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 +		__git -C "$1" -c core.quotePath=false ls-files \ +			--exclude-standard $2 -- "${3//\\/\\\\}*"  	fi  } @@ -346,17 +499,103 @@ __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 root="${2-.}" file +	local root="$2" match="$3" -	__git_ls_files_helper "$root" "$1" | -	while read -r file; do -		case "$file" in -		?*/*) echo "${file%%/*}" ;; -		*) echo "$file" ;; -		esac -	done | sort | uniq +	__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. @@ -439,7 +678,7 @@ __git_refs ()  			track=""  			;;  		*) -			for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD; do +			for i in HEAD FETCH_HEAD ORIG_HEAD MERGE_HEAD REBASE_HEAD; do  				case "$i" in  				$match*)  					if [ -e "$dir/$i" ]; then @@ -594,7 +833,7 @@ __git_is_configured_remote ()  __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/.*:// @@ -616,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 @@ -626,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 @@ -643,21 +891,10 @@ __git_complete_revlist_file ()  		*)   pfx="$ref:$pfx" ;;  		esac -		__gitcomp_nl "$(__git ls-tree "$ls" \ -				| 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_%...*}..." @@ -675,26 +912,6 @@ __git_complete_revlist_file ()  	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}/" -		;; -	esac - -	__gitcomp_file "$(__git_index_files "$1" ${pfx:+"$pfx"})" "$pfx" "$cur_" -} -  __git_complete_file ()  {  	__git_complete_revlist_file @@ -726,6 +943,7 @@ __git_complete_remote_or_refspec ()  			*) ;;  			esac  			;; +		--multiple) no_complete_refspec=1; break ;;  		-*) ;;  		*) remote="$i"; break ;;  		esac @@ -785,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, @@ -932,11 +1044,6 @@ __git_pretty_aliases ()  	__git_get_config_variables "pretty"  } -__git_aliases () -{ -	__git_get_config_variables "alias" -} -  # __git_aliased_command requires 1 argument  __git_aliased_command ()  { @@ -1072,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 ()  {  	__git_find_repo_path  	if [ -d "$__git_repo_path"/rebase-apply ]; then -		__gitcomp "--skip --continue --resolved --abort" +		__gitcomp "$__git_am_inprogress_options"  		return  	fi  	case "$cur" in @@ -1085,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  } @@ -1104,14 +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 -			--recount --directory= -			" +		__gitcomp_builtin apply  		return  	esac  } @@ -1119,11 +1221,12 @@ _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 --force --edit --chmod= -			" +		__gitcomp_builtin add  		return  	esac @@ -1182,6 +1285,8 @@ _git_bisect ()  	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" @@ -1200,13 +1305,7 @@ _git_branch ()  		__git_complete_refs --cur="${cur##--set-upstream-to=}"  		;;  	--*) -		__gitcomp " -			--color --no-color --verbose --abbrev= --no-abbrev -			--track --no-track --contains --no-contains --merged --no-merged -			--set-upstream-to= --edit-description --list -			--unset-upstream --delete --move --copy --remotes -			--column --no-column --sort= --points-at -			" +		__gitcomp_builtin branch  		;;  	*)  		if [ $only_local_ref = "y" -a $has_r = "n" ]; then @@ -1247,11 +1346,7 @@ _git_checkout ()  		__gitcomp "diff3 merge" "" "${cur##--conflict=}"  		;;  	--*) -		__gitcomp " -			--quiet --ours --theirs --track --no-track --merge -			--conflict= --orphan --patch --detach --ignore-skip-worktree-bits -			--recurse-submodules --no-recurse-submodules -			" +		__gitcomp_builtin checkout  		;;  	*)  		# check if --track, --no-track, or --no-guess was specified @@ -1266,21 +1361,22 @@ _git_checkout ()  	esac  } -_git_cherry () -{ -	__git_complete_refs -} +__git_cherry_pick_inprogress_options="--continue --quit --abort"  _git_cherry_pick ()  {  	__git_find_repo_path  	if [ -f "$__git_repo_path"/CHERRY_PICK_HEAD ]; then -		__gitcomp "--continue --quit --abort" +		__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"  		;;  	*)  		__git_complete_refs @@ -1292,7 +1388,7 @@ _git_clean ()  {  	case "$cur" in  	--*) -		__gitcomp "--dry-run --quiet" +		__gitcomp_builtin clean  		return  		;;  	esac @@ -1305,26 +1401,7 @@ _git_clone ()  {  	case "$cur" in  	--*) -		__gitcomp " -			--local -			--no-hardlinks -			--shared -			--reference -			--quiet -			--no-checkout -			--bare -			--mirror -			--origin -			--upload-pack -			--template= -			--depth -			--single-branch -			--no-tags -			--branch -			--recurse-submodules -			--no-single-branch -			--shallow-submodules -			" +		__gitcomp_builtin clone  		return  		;;  	esac @@ -1357,16 +1434,7 @@ _git_commit ()  		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= -			--patch --short --date --allow-empty -			" +		__gitcomp_builtin commit  		return  	esac @@ -1382,11 +1450,7 @@ _git_describe ()  {  	case "$cur" in  	--*) -		__gitcomp " -			--all --tags --contains --abbrev= --candidates= -			--exact-match --debug --long --match --always --first-parent -			--exclude --dirty --broken -			" +		__gitcomp_builtin describe  		return  	esac  	__git_complete_refs @@ -1411,7 +1475,7 @@ __git_diff_common_options="--stat --numstat --shortstat --summary  			--dirstat --dirstat= --dirstat-by-file  			--dirstat-by-file= --cumulative  			--diff-algorithm= -			--submodule --submodule= +			--submodule --submodule= --ignore-submodules  "  _git_diff () @@ -1439,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 () @@ -1452,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 @@ -1465,12 +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= -	--unshallow --update-shallow -" -  _git_fetch ()  {  	case "$cur" in @@ -1478,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 () @@ -1505,7 +1564,7 @@ _git_format_patch ()  		return  		;;  	--*) -		__gitcomp "$__git_format_patch_options" +		__gitcomp_builtin format-patch "$__git_format_patch_extra_options"  		return  		;;  	esac @@ -1516,20 +1575,7 @@ _git_fsck ()  {  	case "$cur" in  	--*) -		__gitcomp " -			--tags --root --unreachable --cache --no-reflogs --full -			--strict --verbose --lost-found --name-objects -			" -		return -		;; -	esac -} - -_git_gc () -{ -	case "$cur" in -	--*) -		__gitcomp "--prune --aggressive" +		__gitcomp_builtin fsck  		return  		;;  	esac @@ -1585,21 +1631,7 @@ _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 -			--break --heading --show-function --function-context -			--untracked --no-index -			" +		__gitcomp_builtin grep  		return  		;;  	esac @@ -1617,17 +1649,16 @@ _git_help ()  {  	case "$cur" in  	--*) -		__gitcomp "--all --guides --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 everyday gitk glossary hooks ignore modules -		namespaces repository-layout revisions 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 () @@ -1640,7 +1671,7 @@ _git_init ()  		return  		;;  	--*) -		__gitcomp "--quiet --bare --template= --shared --shared=" +		__gitcomp_builtin init  		return  		;;  	esac @@ -1650,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 @@ -1670,7 +1695,7 @@ _git_ls_remote ()  {  	case "$cur" in  	--*) -		__gitcomp "--heads --tags --refs --get-url --symref" +		__gitcomp_builtin ls-remote  		return  		;;  	esac @@ -1679,6 +1704,13 @@ _git_ls_remote ()  _git_ls_tree ()  { +	case "$cur" in +	--*) +		__gitcomp_builtin ls-tree +		return +		;; +	esac +  	__git_complete_file  } @@ -1705,8 +1737,8 @@ __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 ()  { @@ -1794,22 +1826,13 @@ _git_log ()  	__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 --continue" +		__gitcomp_builtin merge  		return  	esac  	__git_complete_refs @@ -1823,7 +1846,7 @@ _git_mergetool ()  		return  		;;  	--*) -		__gitcomp "--tool= --prompt --no-prompt" +		__gitcomp "--tool= --prompt --no-prompt --gui --no-gui"  		return  		;;  	esac @@ -1833,7 +1856,7 @@ _git_merge_base ()  {  	case "$cur" in  	--*) -		__gitcomp "--octopus --independent --is-ancestor --fork-point" +		__gitcomp_builtin merge-base  		return  		;;  	esac @@ -1844,7 +1867,7 @@ _git_mv ()  {  	case "$cur" in  	--*) -		__gitcomp "--dry-run" +		__gitcomp_builtin mv  		return  		;;  	esac @@ -1858,19 +1881,14 @@ _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 @@ -1882,21 +1900,14 @@ _git_notes ()  			;;  		esac  		;; -	add,--reuse-message=*|append,--reuse-message=*|\ -	add,--reedit-message=*|append,--reedit-message=*) +	*,--reuse-message=*|*,--reedit-message=*)  		__git_complete_refs --cur="${cur#*=}"  		;; -	add,--*|append,--*) -		__gitcomp '--file= --message= --reedit-message= -				--reuse-message=' -		;; -	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 @@ -1920,12 +1931,8 @@ _git_pull ()  		return  		;;  	--*) -		__gitcomp " -			--rebase --no-rebase -			--autostash --no-autostash -			$__git_merge_options -			$__git_fetch_options -		" +		__gitcomp_builtin pull +  		return  		;;  	esac @@ -1976,27 +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 ()  {  	__git_find_repo_path  	if [ -f "$__git_repo_path"/rebase-merge/interactive ]; then -		__gitcomp "--continue --skip --abort --quit --edit-todo" +		__gitcomp "--continue --skip --abort --quit --edit-todo --show-current-patch"  		return  	elif [ -d "$__git_repo_path"/rebase-apply ] || \  	     [ -d "$__git_repo_path"/rebase-merge ]; then -		__gitcomp "--continue --skip --abort --quit" +		__gitcomp "--continue --skip --abort --quit --show-current-patch"  		return  	fi  	__git_complete_strategy && return @@ -2008,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 @@ -2016,6 +2032,7 @@ _git_rebase ()  			--autostash --no-autostash  			--verify --no-verify  			--keep-empty --root --force-rebase --no-ff +			--rerere-autoupdate  			--exec  			" @@ -2077,16 +2094,16 @@ _git_send_email ()  		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 @@ -2119,11 +2136,7 @@ _git_status ()  		return  		;;  	--*) -		__gitcomp " -			--short --branch --porcelain --long --verbose -			--untracked-files= --ignore-submodules= --ignored -			--column= --no-column -			" +		__gitcomp_builtin status  		return  		;;  	esac @@ -2148,6 +2161,44 @@ _git_status ()  	__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 @@ -2170,9 +2221,24 @@ __git_config_get_set_variables ()  	__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 @@ -2182,7 +2248,7 @@ _git_config ()  		return  		;;  	branch.*.rebase) -		__gitcomp "false true preserve interactive" +		__gitcomp "false true merges preserve interactive"  		return  		;;  	remote.pushdefault) @@ -2228,7 +2294,7 @@ _git_config ()  		return  		;;  	diff.submodule) -		__gitcomp "log short" +		__gitcomp "$__git_diff_submodule_formats"  		return  		;;  	help.format) @@ -2239,7 +2305,7 @@ _git_config ()  		__gitcomp "$__git_log_date_formats"  		return  		;; -	sendemail.aliasesfiletype) +	sendemail.aliasfiletype)  		__gitcomp "mutt mailrc pine elm gnus"  		return  		;; @@ -2265,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_direct "$(__git_heads "$pfx" "$cur_" ".")" -		__gitcomp_nl_append $'autosetupmerge\nautosetuprebase\n' "$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  		;; @@ -2319,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.*.*) @@ -2334,332 +2393,14 @@ _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.amWorkDir -		advice.commitBeforeMerge -		advice.detachedHead -		advice.implicitIdentity -		advice.pushAlreadyExists -		advice.pushFetchFirst -		advice.pushNeedsForce -		advice.pushNonFFCurrent -		advice.pushNonFFMatching -		advice.pushUpdateRejected -		advice.resolveConflict -		advice.rmHints -		advice.statusHints -		advice.statusUoption -		advice.ignoredHook -		alias. -		am.keepcr -		am.threeWay -		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.localBranch -		color.status.nobranch -		color.status.remoteBranch -		color.status.unmerged -		color.status.untracked -		color.status.updated -		color.ui -		commit.cleanup -		commit.gpgSign -		commit.status -		commit.template -		commit.verbose -		core.abbrev -		core.askpass -		core.attributesfile -		core.autocrlf -		core.bare -		core.bigFileThreshold -		core.checkStat -		core.commentChar -		core.compression -		core.createObject -		core.deltaBaseCacheLimit -		core.editor -		core.eol -		core.excludesfile -		core.fileMode -		core.fsyncobjectfiles -		core.gitProxy -		core.hideDotFiles -		core.hooksPath -		core.ignoreStat -		core.ignorecase -		core.logAllRefUpdates -		core.loosecompression -		core.notesRef -		core.packedGitLimit -		core.packedGitWindowSize -		core.packedRefsTimeout -		core.pager -		core.precomposeUnicode -		core.preferSymlinkRefs -		core.preloadindex -		core.protectHFS -		core.protectNTFS -		core.quotepath -		core.repositoryFormatVersion -		core.safecrlf -		core.sharedRepository -		core.sparseCheckout -		core.splitIndex -		core.sshCommand -		core.symlinks -		core.trustctime -		core.untrackedCache -		core.warnAmbiguousRefs -		core.whitespace -		core.worktree -		credential.helper -		credential.useHttpPath -		credential.username -		credentialCache.ignoreSIGHUP -		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.from -		format.headers -		format.numbered -		format.pretty -		format.signature -		format.signoff -		format.subjectprefix -		format.suffix -		format.thread -		format.to -		gc. -		gc.aggressiveDepth -		gc.aggressiveWindow -		gc.auto -		gc.autoDetach -		gc.autopacklimit -		gc.logExpiry -		gc.packrefs -		gc.pruneexpire -		gc.reflogexpire -		gc.reflogexpireunreachable -		gc.rerereresolved -		gc.rerereunresolved -		gc.worktreePruneExpire -		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.tocmd -		sendemail.validate -		sendemail.smtpbatchsize -		sendemail.smtprelogindelay -		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 () @@ -2672,7 +2413,7 @@ _git_remote ()  	if [ -z "$subcommand" ]; then  		case "$cur" in  		--*) -			__gitcomp "--verbose" +			__gitcomp_builtin remote  			;;  		*)  			__gitcomp "$subcommands" @@ -2683,33 +2424,33 @@ _git_remote ()  	case "$subcommand,$cur" in  	add,--*) -		__gitcomp "--track --master --fetch --tags --no-tags --mirror=" +		__gitcomp_builtin remote_add  		;;  	add,*)  		;;  	set-head,--*) -		__gitcomp "--auto --delete" +		__gitcomp_builtin remote_set-head  		;;  	set-branches,--*) -		__gitcomp "--add" +		__gitcomp_builtin remote_set-branches  		;;  	set-head,*|set-branches,*)  		__git_complete_remote_or_refspec  		;;  	update,--*) -		__gitcomp "--prune" +		__gitcomp_builtin remote_update  		;;  	update,*) -		__gitcomp "$(__git_get_config_variables "remotes")" +		__gitcomp "$(__git_remotes) $(__git_get_config_variables "remotes")"  		;;  	set-url,--*) -		__gitcomp "--push --add --delete" +		__gitcomp_builtin remote_set-url  		;;  	get-url,--*) -		__gitcomp "--push --all" +		__gitcomp_builtin remote_get-url  		;;  	prune,--*) -		__gitcomp "--dry-run" +		__gitcomp_builtin remote_prune  		;;  	*)  		__gitcomp_nl "$(__git_remotes)" @@ -2720,8 +2461,12 @@ _git_remote ()  _git_replace ()  {  	case "$cur" in +	--format=*) +		__gitcomp "short medium long" "" "${cur##--format=}" +		return +		;;  	--*) -		__gitcomp "--edit --graft --format= --list --delete" +		__gitcomp_builtin replace  		return  		;;  	esac @@ -2745,26 +2490,42 @@ _git_reset ()  	case "$cur" in  	--*) -		__gitcomp "--merge --mixed --hard --soft --patch --keep" +		__gitcomp_builtin reset  		return  		;;  	esac  	__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 ()  {  	__git_find_repo_path  	if [ -f "$__git_repo_path"/REVERT_HEAD ]; then -		__gitcomp "--continue --quit --abort" +		__gitcomp "$__git_revert_inprogress_options"  		return  	fi +	__git_complete_strategy && return  	case "$cur" in  	--*) -		__gitcomp " -			--edit --mainline --no-edit --no-commit --signoff -			--strategy= --strategy-option= -			" +		__gitcomp_builtin revert "" \ +			"$__git_revert_inprogress_options"  		return  		;;  	esac @@ -2775,7 +2536,7 @@ _git_rm ()  {  	case "$cur" in  	--*) -		__gitcomp "--cached --dry-run --ignore-unmatch --quiet" +		__gitcomp_builtin rm  		return  		;;  	esac @@ -2833,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 @@ -2848,13 +2604,21 @@ _git_show_branch ()  _git_stash ()  {  	local save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked' -	local subcommands='push 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" @@ -2875,6 +2639,9 @@ _git_stash ()  		drop,--*)  			__gitcomp "--quiet"  			;; +		list,--*) +			__gitcomp "--name-status --oneline --patch-with-stat" +			;;  		show,--*|branch,--*)  			;;  		branch,*) @@ -2899,7 +2666,7 @@ _git_submodule ()  {  	__git_has_doubledash && return -	local subcommands="add status init deinit update summary foreach sync" +	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 @@ -2930,6 +2697,9 @@ _git_submodule ()  			--force --rebase --merge --reference --depth --recursive --jobs  		"  		;; +	set-branch,--*) +		__gitcomp "--default --branch" +		;;  	summary,--*)  		__gitcomp "--cached --files --summary-limit"  		;; @@ -3045,7 +2815,7 @@ _git_tag ()  	while [ $c -lt $cword ]; do  		i="${words[c]}"  		case "$i" in -		-d|-v) +		-d|--delete|-v|--verify)  			__gitcomp_direct "$(__git_tags "" "$cur" " ")"  			return  			;; @@ -3071,11 +2841,7 @@ _git_tag ()  	case "$cur" in  	--*) -		__gitcomp " -			--list --delete --verify --annotate --message --file -			--sign --cleanup --local-user --force --column --sort= -			--contains --no-contains --points-at --merged --no-merged --create-reflog -			" +		__gitcomp_builtin tag  		;;  	esac  } @@ -3087,23 +2853,26 @@ _git_whatchanged ()  _git_worktree ()  { -	local subcommands="add list lock prune unlock" +	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 "--detach" +			__gitcomp_builtin worktree_add  			;;  		list,--*) -			__gitcomp "--porcelain" +			__gitcomp_builtin worktree_list  			;;  		lock,--*) -			__gitcomp "--reason" +			__gitcomp_builtin worktree_lock  			;;  		prune,--*) -			__gitcomp "--dry-run --expire --verbose" +			__gitcomp_builtin worktree_prune +			;; +		remove,--*) +			__gitcomp "--force"  			;;  		*)  			;; @@ -3111,6 +2880,52 @@ _git_worktree ()  	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 __git_repo_path @@ -3164,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 2>/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 2>/dev/null && $completion_func +		__git_complete_command "$expansion"  	fi  } @@ -3205,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 @@ -3254,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 () @@ -3315,6 +3146,6 @@ __git_complete gitk __gitk_main  # when the user has tab-completed the executable name and consequently  # included the '.exe' suffix.  # -if [[ "$OSTYPE" = cygwin* ]]; then +if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then  __git_complete git.exe __git_main  fi | 
