# git@vger.kernel.org
#
+case "$COMP_WORDBREAKS" in
+*:*) : great ;;
+*) COMP_WORDBREAKS="$COMP_WORDBREAKS:"
+esac
+
__gitdir ()
{
if [ -z "$1" ]; then
if [ -n "$g" ]; then
local r
local b
- if [ -d "$g/../.dotest" ]
+ if [ -d "$g/rebase-apply" ]
then
- if test -f "$g/../.dotest/rebasing"
+ if test -f "$g/rebase-apply/rebasing"
then
r="|REBASE"
- elif test -f "$g/../.dotest/applying"
+ elif test -f "$g/rebase-apply/applying"
then
r="|AM"
else
r="|AM/REBASE"
fi
b="$(git symbolic-ref HEAD 2>/dev/null)"
- elif [ -f "$g/.dotest-merge/interactive" ]
+ elif [ -f "$g/rebase-merge/interactive" ]
then
r="|REBASE-i"
- b="$(cat "$g/.dotest-merge/head-name")"
- elif [ -d "$g/.dotest-merge" ]
+ b="$(cat "$g/rebase-merge/head-name")"
+ elif [ -d "$g/rebase-merge" ]
then
r="|REBASE-m"
- b="$(cat "$g/.dotest-merge/head-name")"
+ b="$(cat "$g/rebase-merge/head-name")"
elif [ -f "$g/MERGE_HEAD" ]
then
r="|MERGING"
fi
}
+__gitcomp_1 ()
+{
+ local c IFS=' '$'\t'$'\n'
+ for c in $1; do
+ case "$c$2" in
+ --*=*) printf %s$'\n' "$c$2" ;;
+ *.) printf %s$'\n' "$c$2" ;;
+ *) printf %s$'\n' "$c$2 " ;;
+ esac
+ done
+}
+
__gitcomp ()
{
- local all c s=$'\n' IFS=' '$'\t'$'\n'
local cur="${COMP_WORDS[COMP_CWORD]}"
if [ $# -gt 2 ]; then
cur="$3"
case "$cur" in
--*=)
COMPREPLY=()
- return
;;
*)
- for c in $1; do
- case "$c$4" in
- --*=*) all="$all$c$4$s" ;;
- *.) all="$all$c$4$s" ;;
- *) all="$all$c$4 $s" ;;
- esac
- done
+ local IFS=$'\n'
+ COMPREPLY=($(compgen -P "$2" \
+ -W "$(__gitcomp_1 "$1" "$4")" \
+ -- "$cur"))
;;
esac
- IFS=$s
- COMPREPLY=($(compgen -P "$2" -W "$all" -- "$cur"))
- return
}
__git_heads ()
ls="$ref"
;;
esac
+
+ case "$COMP_WORDBREAKS" in
+ *:*) : great ;;
+ *) pfx="$ref:$pfx" ;;
+ esac
+
+ local IFS=$'\n'
COMPREPLY=($(compgen -P "$pfx" \
-W "$(git --git-dir="$(__gitdir)" ls-tree "$ls" \
- | sed '/^100... blob /s,^.* ,,
+ | sed '/^100... blob /{
+ s,^.* ,,
+ s,$, ,
+ }
+ /^120000 blob /{
+ s,^.* ,,
+ s,$, ,
+ }
/^040000 tree /{
s,^.* ,,
s,$,/,
cur="${cur#*..}"
__gitcomp "$(__git_refs)" "$pfx" "$cur"
;;
- *.)
- __gitcomp "$cur."
- ;;
*)
__gitcomp "$(__git_refs)"
;;
esac
}
-__git_commands ()
+__git_all_commands ()
{
- if [ -n "$__git_commandlist" ]; then
- echo "$__git_commandlist"
+ if [ -n "$__git_all_commandlist" ]; then
+ echo "$__git_all_commandlist"
return
fi
local i IFS=" "$'\n'
for i in $(git help -a|egrep '^ ')
+ do
+ case $i in
+ *--*) : helper pattern;;
+ *) echo $i;;
+ esac
+ done
+}
+__git_all_commandlist=
+__git_all_commandlist="$(__git_all_commands 2>/dev/null)"
+
+__git_porcelain_commands ()
+{
+ if [ -n "$__git_porcelain_commandlist" ]; then
+ echo "$__git_porcelain_commandlist"
+ return
+ fi
+ local i IFS=" "$'\n'
+ for i in "help" $(__git_all_commands)
do
case $i in
*--*) : helper pattern;;
esac
done
}
-__git_commandlist=
-__git_commandlist="$(__git_commands 2>/dev/null)"
+__git_porcelain_commandlist=
+__git_porcelain_commandlist="$(__git_porcelain_commands 2>/dev/null)"
__git_aliases ()
{
done
}
+__git_has_doubledash ()
+{
+ local c=1
+ while [ $c -lt $COMP_CWORD ]; do
+ if [ "--" = "${COMP_WORDS[c]}" ]; then
+ return 0
+ fi
+ c=$((++c))
+ done
+ return 1
+}
+
__git_whitespacelist="nowarn warn error error-all strip"
_git_am ()
{
- local cur="${COMP_WORDS[COMP_CWORD]}"
- if [ -d .dotest ]; then
- __gitcomp "--skip --resolved"
+ local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
+ if [ -d "$dir"/rebase-apply ]; then
+ __gitcomp "--skip --resolved --abort"
return
fi
case "$cur" in
_git_add ()
{
+ __git_has_doubledash && return
+
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
COMPREPLY=()
}
+_git_archive ()
+{
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --format=*)
+ __gitcomp "$(git archive --list)" "" "${cur##--format=}"
+ return
+ ;;
+ --remote=*)
+ __gitcomp "$(__git_remotes)" "" "${cur##--remote=}"
+ return
+ ;;
+ --*)
+ __gitcomp "
+ --format= --list --verbose
+ --prefix= --remote= --exec=
+ "
+ return
+ ;;
+ esac
+ __git_complete_file
+}
+
_git_bisect ()
{
- local subcommands="start bad good reset visualize replay log"
+ __git_has_doubledash && return
+
+ local subcommands="start bad good skip reset visualize replay log run"
local subcommand="$(__git_find_subcommand "$subcommands")"
if [ -z "$subcommand" ]; then
__gitcomp "$subcommands"
fi
case "$subcommand" in
- bad|good|reset)
+ bad|good|reset|skip)
__gitcomp "$(__git_refs)"
;;
*)
--*)
__gitcomp "
--color --no-color --verbose --abbrev= --no-abbrev
- --track --no-track
+ --track --no-track --contains --merged --no-merged
"
;;
*)
_git_checkout ()
{
+ __git_has_doubledash && return
+
__gitcomp "$(__git_refs)"
}
esac
}
+_git_clean ()
+{
+ __git_has_doubledash && return
+
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --*)
+ __gitcomp "--dry-run --quiet"
+ return
+ ;;
+ esac
+ COMPREPLY=()
+}
+
+_git_clone ()
+{
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --*)
+ __gitcomp "
+ --local
+ --no-hardlinks
+ --shared
+ --reference
+ --quiet
+ --no-checkout
+ --bare
+ --mirror
+ --origin
+ --upload-pack
+ --template=
+ --depth
+ "
+ return
+ ;;
+ esac
+ COMPREPLY=()
+}
+
_git_commit ()
{
+ __git_has_doubledash && return
+
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
_git_describe ()
{
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --*)
+ __gitcomp "
+ --all --tags --contains --abbrev= --candidates=
+ --exact-match --debug --long --match --always
+ "
+ return
+ esac
__gitcomp "$(__git_refs)"
}
_git_diff ()
{
+ __git_has_doubledash && return
+
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
__git_complete_file
}
-_git_diff_tree ()
-{
- __gitcomp "$(__git_refs)"
-}
-
_git_fetch ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
*)
case "$cur" in
*:*)
- __gitcomp "$(__git_refs)" "" "${cur#*:}"
+ local pfx=""
+ case "$COMP_WORDBREAKS" in
+ *:*) : great ;;
+ *) pfx="${cur%%:*}:" ;;
+ esac
+ __gitcomp "$(__git_refs)" "$pfx" "${cur#*:}"
;;
*)
local remote
COMPREPLY=()
}
+_git_grep ()
+{
+ __git_has_doubledash && return
+
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --*)
+ __gitcomp "
+ --cached
+ --text --ignore-case --word-regexp --invert-match
+ --full-name
+ --extended-regexp --basic-regexp --fixed-strings
+ --files-with-matches --name-only
+ --files-without-match
+ --count
+ --and --or --not --all-match
+ "
+ return
+ ;;
+ esac
+ COMPREPLY=()
+}
+
+_git_help ()
+{
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --*)
+ __gitcomp "--all --info --man --web"
+ return
+ ;;
+ esac
+ __gitcomp "$(__git_all_commands)"
+}
+
+_git_init ()
+{
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --shared=*)
+ __gitcomp "
+ false true umask group all world everybody
+ " "" "${cur##--shared=}"
+ return
+ ;;
+ --*)
+ __gitcomp "--quiet --bare --template= --shared --shared="
+ return
+ ;;
+ esac
+ COMPREPLY=()
+}
+
+_git_ls_files ()
+{
+ __git_has_doubledash && return
+
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ 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
+ "
+ return
+ ;;
+ esac
+ COMPREPLY=()
+}
+
_git_ls_remote ()
{
__gitcomp "$(__git_remotes)"
_git_log ()
{
+ __git_has_doubledash && return
+
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--pretty=*)
--stat --numstat --shortstat
--decorate --diff-filter=
--color-words --walk-reflogs
+ --parents --children --full-history
"
return
;;
__gitcomp "$(__git_refs)"
}
+_git_mv ()
+{
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --*)
+ __gitcomp "--dry-run"
+ return
+ ;;
+ esac
+ COMPREPLY=()
+}
+
_git_name_rev ()
{
__gitcomp "--tags --all --stdin"
git-push) remote="${COMP_WORDS[1]}" ;;
git) remote="${COMP_WORDS[2]}" ;;
esac
- __gitcomp "$(__git_refs "$remote")" "" "${cur#*:}"
+
+ local pfx=""
+ case "$COMP_WORDBREAKS" in
+ *:*) : great ;;
+ *) pfx="${cur%%:*}:" ;;
+ esac
+
+ __gitcomp "$(__git_refs "$remote")" "$pfx" "${cur#*:}"
;;
+*)
__gitcomp "$(__git_refs)" + "${cur#+}"
_git_rebase ()
{
local cur="${COMP_WORDS[COMP_CWORD]}" dir="$(__gitdir)"
- if [ -d .dotest ] || [ -d "$dir"/.dotest-merge ]; then
+ if [ -d "$dir"/rebase-apply ] || [ -d "$dir"/rebase-merge ]; then
__gitcomp "--continue --skip --abort"
return
fi
__gitcomp "$(__git_refs)"
}
+_git_send_email ()
+{
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --*)
+ __gitcomp "--bcc --cc --cc-cmd --chain-reply-to --compose
+ --dry-run --envelope-sender --from --identity
+ --in-reply-to --no-chain-reply-to --no-signed-off-by-cc
+ --no-suppress-from --no-thread --quiet
+ --signed-off-by-cc --smtp-pass --smtp-server
+ --smtp-server-port --smtp-ssl --smtp-user --subject
+ --suppress-cc --suppress-from --thread --to"
+ return
+ ;;
+ esac
+ COMPREPLY=()
+}
+
_git_config ()
{
local cur="${COMP_WORDS[COMP_CWORD]}"
_git_reset ()
{
+ __git_has_doubledash && return
+
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
__gitcomp "$(__git_refs)"
}
+_git_revert ()
+{
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --*)
+ __gitcomp "--edit --mainline --no-edit --no-commit --signoff"
+ return
+ ;;
+ esac
+ COMPREPLY=()
+}
+
+_git_rm ()
+{
+ __git_has_doubledash && return
+
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --*)
+ __gitcomp "--cached --dry-run --ignore-unmatch --quiet"
+ return
+ ;;
+ esac
+ COMPREPLY=()
+}
+
_git_shortlog ()
{
+ __git_has_doubledash && return
+
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$cur" in
--*)
__git_complete_file
}
+_git_show_branch ()
+{
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$cur" in
+ --*)
+ __gitcomp "
+ --all --remotes --topo-order --current --more=
+ --list --independent --merge-base --no-name
+ --sha1-name --topics --reflog
+ "
+ return
+ ;;
+ esac
+ __git_complete_revlist
+}
+
_git_stash ()
{
- local subcommands='save list show apply clear drop pop create'
- if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
+ local subcommands='save list show apply clear drop pop create branch'
+ local subcommand="$(__git_find_subcommand "$subcommands")"
+ if [ -z "$subcommand" ]; then
__gitcomp "$subcommands"
+ else
+ local cur="${COMP_WORDS[COMP_CWORD]}"
+ case "$subcommand,$cur" in
+ save,--*)
+ __gitcomp "--keep-index"
+ ;;
+ apply,--*)
+ __gitcomp "--index"
+ ;;
+ show,--*|apply,--*|drop,--*|pop,--*|branch,--*)
+ COMPREPLY=()
+ ;;
+ show,*|apply,*|drop,*|pop,*|branch,*)
+ __gitcomp "$(git --git-dir="$(__gitdir)" stash list \
+ | sed -n -e 's/:.*//p')"
+ ;;
+ *)
+ COMPREPLY=()
+ ;;
+ esac
fi
}
_git_submodule ()
{
+ __git_has_doubledash && return
+
local subcommands="add status init update"
if [ -z "$(__git_find_subcommand "$subcommands")" ]; then
local cur="${COMP_WORDS[COMP_CWORD]}"
case "$i" in
--git-dir=*) __git_dir="${i#--git-dir=}" ;;
--bare) __git_dir="." ;;
- --version|--help|-p|--paginate) ;;
+ --version|-p|--paginate) ;;
+ --help) command="help"; break ;;
*) command="$i"; break ;;
esac
c=$((++c))
--help
"
;;
- *) __gitcomp "$(__git_commands) $(__git_aliases)" ;;
+ *) __gitcomp "$(__git_porcelain_commands) $(__git_aliases)" ;;
esac
return
fi
am) _git_am ;;
add) _git_add ;;
apply) _git_apply ;;
+ archive) _git_archive ;;
bisect) _git_bisect ;;
bundle) _git_bundle ;;
branch) _git_branch ;;
checkout) _git_checkout ;;
cherry) _git_cherry ;;
cherry-pick) _git_cherry_pick ;;
+ clean) _git_clean ;;
+ clone) _git_clone ;;
commit) _git_commit ;;
config) _git_config ;;
describe) _git_describe ;;
fetch) _git_fetch ;;
format-patch) _git_format_patch ;;
gc) _git_gc ;;
+ grep) _git_grep ;;
+ help) _git_help ;;
+ init) _git_init ;;
log) _git_log ;;
+ ls-files) _git_ls_files ;;
ls-remote) _git_ls_remote ;;
ls-tree) _git_ls_tree ;;
merge) _git_merge;;
merge-base) _git_merge_base ;;
+ mv) _git_mv ;;
name-rev) _git_name_rev ;;
pull) _git_pull ;;
push) _git_push ;;
rebase) _git_rebase ;;
remote) _git_remote ;;
reset) _git_reset ;;
+ revert) _git_revert ;;
+ rm) _git_rm ;;
+ send-email) _git_send_email ;;
shortlog) _git_shortlog ;;
show) _git_show ;;
- show-branch) _git_log ;;
+ show-branch) _git_show_branch ;;
stash) _git_stash ;;
submodule) _git_submodule ;;
svn) _git_svn ;;
_gitk ()
{
+ __git_has_doubledash && return
+
local cur="${COMP_WORDS[COMP_CWORD]}"
local g="$(git rev-parse --git-dir 2>/dev/null)"
local merge=""
complete -o default -o nospace -F _git git
complete -o default -o nospace -F _gitk gitk
-complete -o default -o nospace -F _git_am git-am
-complete -o default -o nospace -F _git_apply git-apply
-complete -o default -o nospace -F _git_bisect git-bisect
-complete -o default -o nospace -F _git_branch git-branch
-complete -o default -o nospace -F _git_bundle git-bundle
-complete -o default -o nospace -F _git_checkout git-checkout
-complete -o default -o nospace -F _git_cherry git-cherry
-complete -o default -o nospace -F _git_cherry_pick git-cherry-pick
-complete -o default -o nospace -F _git_commit git-commit
-complete -o default -o nospace -F _git_describe git-describe
-complete -o default -o nospace -F _git_diff git-diff
-complete -o default -o nospace -F _git_fetch git-fetch
-complete -o default -o nospace -F _git_format_patch git-format-patch
-complete -o default -o nospace -F _git_gc git-gc
-complete -o default -o nospace -F _git_log git-log
-complete -o default -o nospace -F _git_ls_remote git-ls-remote
-complete -o default -o nospace -F _git_ls_tree git-ls-tree
-complete -o default -o nospace -F _git_merge git-merge
-complete -o default -o nospace -F _git_merge_base git-merge-base
-complete -o default -o nospace -F _git_name_rev git-name-rev
-complete -o default -o nospace -F _git_pull git-pull
-complete -o default -o nospace -F _git_push git-push
-complete -o default -o nospace -F _git_rebase git-rebase
-complete -o default -o nospace -F _git_config git-config
-complete -o default -o nospace -F _git_remote git-remote
-complete -o default -o nospace -F _git_reset git-reset
-complete -o default -o nospace -F _git_shortlog git-shortlog
-complete -o default -o nospace -F _git_show git-show
-complete -o default -o nospace -F _git_stash git-stash
-complete -o default -o nospace -F _git_submodule git-submodule
-complete -o default -o nospace -F _git_svn git-svn
-complete -o default -o nospace -F _git_log git-show-branch
-complete -o default -o nospace -F _git_tag git-tag
-complete -o default -o nospace -F _git_log git-whatchanged
# The following are necessary only for Cygwin, and only are needed
# when the user has tab-completed the executable name and consequently
# included the '.exe' suffix.
#
if [ Cygwin = "$(uname -o 2>/dev/null)" ]; then
-complete -o default -o nospace -F _git_add git-add.exe
-complete -o default -o nospace -F _git_apply git-apply.exe
complete -o default -o nospace -F _git git.exe
-complete -o default -o nospace -F _git_branch git-branch.exe
-complete -o default -o nospace -F _git_bundle git-bundle.exe
-complete -o default -o nospace -F _git_cherry git-cherry.exe
-complete -o default -o nospace -F _git_describe git-describe.exe
-complete -o default -o nospace -F _git_diff git-diff.exe
-complete -o default -o nospace -F _git_format_patch git-format-patch.exe
-complete -o default -o nospace -F _git_log git-log.exe
-complete -o default -o nospace -F _git_ls_tree git-ls-tree.exe
-complete -o default -o nospace -F _git_merge_base git-merge-base.exe
-complete -o default -o nospace -F _git_name_rev git-name-rev.exe
-complete -o default -o nospace -F _git_push git-push.exe
-complete -o default -o nospace -F _git_config git-config
-complete -o default -o nospace -F _git_shortlog git-shortlog.exe
-complete -o default -o nospace -F _git_show git-show.exe
-complete -o default -o nospace -F _git_log git-show-branch.exe
-complete -o default -o nospace -F _git_tag git-tag.exe
-complete -o default -o nospace -F _git_log git-whatchanged.exe
fi