Browse Source

Merge branch 'sg/complete-refs'

* sg/complete-refs:
  completion: remove broken dead code from __git_heads() and __git_tags()
  completion: fast initial completion for config 'remote.*.fetch' value
  completion: improve ls-remote output filtering in __git_refs_remotes()
  completion: query only refs/heads/ in __git_refs_remotes()
  completion: support full refs from remote repositories
  completion: improve ls-remote output filtering in __git_refs()
  completion: make refs completion consistent for local and remote repos
  completion: optimize refs completion
  completion: document __gitcomp()

Conflicts:
	contrib/completion/git-completion.bash
maint
Junio C Hamano 13 years ago
parent
commit
d2c7807549
  1. 201
      contrib/completion/git-completion.bash

201
contrib/completion/git-completion.bash

@ -486,8 +486,13 @@ _get_comp_words_by_ref () @@ -486,8 +486,13 @@ _get_comp_words_by_ref ()
fi
fi

# __gitcomp accepts 1, 2, 3, or 4 arguments
# generates completion reply with compgen
# Generates completion reply with compgen, appending a space to possible
# completion words, if necessary.
# It accepts 1 to 4 arguments:
# 1: List of possible completion words.
# 2: A prefix to be added to each possible completion word (optional).
# 3: Generate possible completion matches for this word (optional).
# 4: A suffix to be appended to each possible completion word (optional).
__gitcomp ()
{
local cur_="$cur"
@ -508,42 +513,49 @@ __gitcomp () @@ -508,42 +513,49 @@ __gitcomp ()
esac
}

# __git_heads accepts 0 or 1 arguments (to pass to __gitdir)
# Generates completion reply with compgen from newline-separated possible
# completion words by appending a space to all of them.
# It accepts 1 to 4 arguments:
# 1: List of possible completion words, separated by a single newline.
# 2: A prefix to be added to each possible completion word (optional).
# 3: Generate possible completion matches for this word (optional).
# 4: A suffix to be appended to each possible completion word instead of
# the default space (optional). If specified but empty, nothing is
# appended.
__gitcomp_nl ()
{
local s=$'\n' IFS=' '$'\t'$'\n'
local cur_="$cur" suffix=" "

if [ $# -gt 2 ]; then
cur_="$3"
if [ $# -gt 3 ]; then
suffix="$4"
fi
fi

IFS=$s
COMPREPLY=($(compgen -P "${2-}" -S "$suffix" -W "$1" -- "$cur_"))
}

__git_heads ()
{
local cmd i is_hash=y dir="$(__gitdir "${1-}")"
local dir="$(__gitdir)"
if [ -d "$dir" ]; then
git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
refs/heads
return
fi
for i in $(git ls-remote "${1-}" 2>/dev/null); do
case "$is_hash,$i" in
y,*) is_hash=n ;;
n,*^{}) is_hash=y ;;
n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
n,*) is_hash=y; echo "$i" ;;
esac
done
}

# __git_tags accepts 0 or 1 arguments (to pass to __gitdir)
__git_tags ()
{
local cmd i is_hash=y dir="$(__gitdir "${1-}")"
local dir="$(__gitdir)"
if [ -d "$dir" ]; then
git --git-dir="$dir" for-each-ref --format='%(refname:short)' \
refs/tags
return
fi
for i in $(git ls-remote "${1-}" 2>/dev/null); do
case "$is_hash,$i" in
y,*) is_hash=n ;;
n,*^{}) is_hash=y ;;
n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
n,*) is_hash=y; echo "$i" ;;
esac
done
}

# __git_refs accepts 0, 1 (to pass to __gitdir), or 2 arguments
@ -551,7 +563,7 @@ __git_tags () @@ -551,7 +563,7 @@ __git_tags ()
# by checkout for tracking branches
__git_refs ()
{
local i is_hash=y dir="$(__gitdir "${1-}")" track="${2-}"
local i hash dir="$(__gitdir "${1-}")" track="${2-}"
local format refs
if [ -d "$dir" ]; then
case "$cur" in
@ -587,16 +599,27 @@ __git_refs () @@ -587,16 +599,27 @@ __git_refs ()
fi
return
fi
for i in $(git ls-remote "$dir" 2>/dev/null); do
case "$is_hash,$i" in
y,*) is_hash=n ;;
n,*^{}) is_hash=y ;;
n,refs/tags/*) is_hash=y; echo "${i#refs/tags/}" ;;
n,refs/heads/*) is_hash=y; echo "${i#refs/heads/}" ;;
n,refs/remotes/*) is_hash=y; echo "${i#refs/remotes/}" ;;
n,*) is_hash=y; echo "$i" ;;
esac
done
case "$cur" in
refs|refs/*)
git ls-remote "$dir" "$cur*" 2>/dev/null | \
while read hash i; do
case "$i" in
*^{}) ;;
*) echo "$i" ;;
esac
done
;;
*)
git ls-remote "$dir" HEAD ORIG_HEAD 'refs/tags/*' 'refs/heads/*' 'refs/remotes/*' 2>/dev/null | \
while read hash i; do
case "$i" in
*^{}) ;;
refs/*) echo "${i#refs/*/}" ;;
*) echo "$i" ;;
esac
done
;;
esac
}

# __git_refs2 requires 1 argument (to pass to __git_refs)
@ -611,18 +634,10 @@ __git_refs2 () @@ -611,18 +634,10 @@ __git_refs2 ()
# __git_refs_remotes requires 1 argument (to pass to ls-remote)
__git_refs_remotes ()
{
local cmd i is_hash=y
for i in $(git ls-remote "$1" 2>/dev/null); do
case "$is_hash,$i" in
n,refs/heads/*)
is_hash=y
echo "$i:refs/remotes/$1/${i#refs/heads/}"
;;
y,*) is_hash=n ;;
n,*^{}) is_hash=y ;;
n,refs/tags/*) is_hash=y;;
n,*) is_hash=y; ;;
esac
local i hash
git ls-remote "$1" 'refs/heads/*' 2>/dev/null | \
while read hash i; do
echo "$i:refs/remotes/$1/${i#refs/heads/}"
done
}

@ -712,15 +727,15 @@ __git_complete_revlist_file () @@ -712,15 +727,15 @@ __git_complete_revlist_file ()
*...*)
pfx="${cur_%...*}..."
cur_="${cur_#*...}"
__gitcomp "$(__git_refs)" "$pfx" "$cur_"
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
;;
*..*)
pfx="${cur_%..*}.."
cur_="${cur_#*..}"
__gitcomp "$(__git_refs)" "$pfx" "$cur_"
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
;;
*)
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
;;
esac
}
@ -760,7 +775,7 @@ __git_complete_remote_or_refspec () @@ -760,7 +775,7 @@ __git_complete_remote_or_refspec ()
c=$((++c))
done
if [ -z "$remote" ]; then
__gitcomp "$(__git_remotes)"
__gitcomp_nl "$(__git_remotes)"
return
fi
if [ $no_complete_refspec = 1 ]; then
@ -785,23 +800,23 @@ __git_complete_remote_or_refspec () @@ -785,23 +800,23 @@ __git_complete_remote_or_refspec ()
case "$cmd" in
fetch)
if [ $lhs = 1 ]; then
__gitcomp "$(__git_refs2 "$remote")" "$pfx" "$cur_"
__gitcomp_nl "$(__git_refs2 "$remote")" "$pfx" "$cur_"
else
__gitcomp "$(__git_refs)" "$pfx" "$cur_"
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
fi
;;
pull)
if [ $lhs = 1 ]; then
__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur_"
__gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
else
__gitcomp "$(__git_refs)" "$pfx" "$cur_"
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
fi
;;
push)
if [ $lhs = 1 ]; then
__gitcomp "$(__git_refs)" "$pfx" "$cur_"
__gitcomp_nl "$(__git_refs)" "$pfx" "$cur_"
else
__gitcomp "$(__git_refs "$remote")" "$pfx" "$cur_"
__gitcomp_nl "$(__git_refs "$remote")" "$pfx" "$cur_"
fi
;;
esac
@ -1080,7 +1095,7 @@ _git_archive () @@ -1080,7 +1095,7 @@ _git_archive ()
return
;;
--remote=*)
__gitcomp "$(__git_remotes)" "" "${cur##--remote=}"
__gitcomp_nl "$(__git_remotes)" "" "${cur##--remote=}"
return
;;
--*)
@ -1111,7 +1126,7 @@ _git_bisect () @@ -1111,7 +1126,7 @@ _git_bisect ()

case "$subcommand" in
bad|good|reset|skip|start)
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
;;
*)
COMPREPLY=()
@ -1142,9 +1157,9 @@ _git_branch () @@ -1142,9 +1157,9 @@ _git_branch ()
;;
*)
if [ $only_local_ref = "y" -a $has_r = "n" ]; then
__gitcomp "$(__git_heads)"
__gitcomp_nl "$(__git_heads)"
else
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
fi
;;
esac
@ -1191,7 +1206,7 @@ _git_checkout () @@ -1191,7 +1206,7 @@ _git_checkout ()
if [ -n "$(__git_find_on_cmdline "$flags")" ]; then
track=''
fi
__gitcomp "$(__git_refs '' $track)"
__gitcomp_nl "$(__git_refs '' $track)"
;;
esac
}
@ -1208,7 +1223,7 @@ _git_cherry_pick () @@ -1208,7 +1223,7 @@ _git_cherry_pick ()
__gitcomp "--edit --no-commit"
;;
*)
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
;;
esac
}
@ -1262,7 +1277,7 @@ _git_commit () @@ -1262,7 +1277,7 @@ _git_commit ()
;;
--reuse-message=*|--reedit-message=*|\
--fixup=*|--squash=*)
__gitcomp "$(__git_refs)" "" "${cur#*=}"
__gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
return
;;
--untracked-files=*)
@ -1293,7 +1308,7 @@ _git_describe () @@ -1293,7 +1308,7 @@ _git_describe ()
"
return
esac
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
}

__git_diff_common_options="--stat --numstat --shortstat --summary
@ -1459,13 +1474,13 @@ _git_grep () @@ -1459,13 +1474,13 @@ _git_grep ()
case "$cword,$prev" in
2,*|*,-*)
if test -r tags; then
__gitcomp "$(__git_match_ctag "$cur" tags)"
__gitcomp_nl "$(__git_match_ctag "$cur" tags)"
return
fi
;;
esac

__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
}

_git_help ()
@ -1523,7 +1538,7 @@ _git_ls_files () @@ -1523,7 +1538,7 @@ _git_ls_files ()

_git_ls_remote ()
{
__gitcomp "$(__git_remotes)"
__gitcomp_nl "$(__git_remotes)"
}

_git_ls_tree ()
@ -1619,7 +1634,7 @@ _git_merge () @@ -1619,7 +1634,7 @@ _git_merge ()
__gitcomp "$__git_merge_options"
return
esac
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
}

_git_mergetool ()
@ -1639,7 +1654,7 @@ _git_mergetool () @@ -1639,7 +1654,7 @@ _git_mergetool ()

_git_merge_base ()
{
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
}

_git_mv ()
@ -1670,7 +1685,7 @@ _git_notes () @@ -1670,7 +1685,7 @@ _git_notes ()
,*)
case "${words[cword-1]}" in
--ref)
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
;;
*)
__gitcomp "$subcommands --ref"
@ -1679,7 +1694,7 @@ _git_notes () @@ -1679,7 +1694,7 @@ _git_notes ()
;;
add,--reuse-message=*|append,--reuse-message=*|\
add,--reedit-message=*|append,--reedit-message=*)
__gitcomp "$(__git_refs)" "" "${cur#*=}"
__gitcomp_nl "$(__git_refs)" "" "${cur#*=}"
;;
add,--*|append,--*)
__gitcomp '--file= --message= --reedit-message=
@ -1698,7 +1713,7 @@ _git_notes () @@ -1698,7 +1713,7 @@ _git_notes ()
-m|-F)
;;
*)
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
;;
esac
;;
@ -1726,12 +1741,12 @@ _git_push () @@ -1726,12 +1741,12 @@ _git_push ()
{
case "$prev" in
--repo)
__gitcomp "$(__git_remotes)"
__gitcomp_nl "$(__git_remotes)"
return
esac
case "$cur" in
--repo=*)
__gitcomp "$(__git_remotes)" "" "${cur##--repo=}"
__gitcomp_nl "$(__git_remotes)" "" "${cur##--repo=}"
return
;;
--*)
@ -1769,7 +1784,7 @@ _git_rebase () @@ -1769,7 +1784,7 @@ _git_rebase ()

return
esac
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
}

_git_reflog ()
@ -1780,7 +1795,7 @@ _git_reflog () @@ -1780,7 +1795,7 @@ _git_reflog ()
if [ -z "$subcommand" ]; then
__gitcomp "$subcommands"
else
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
fi
}

@ -1862,23 +1877,27 @@ _git_config () @@ -1862,23 +1877,27 @@ _git_config ()
{
case "$prev" in
branch.*.remote)
__gitcomp "$(__git_remotes)"
__gitcomp_nl "$(__git_remotes)"
return
;;
branch.*.merge)
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
return
;;
remote.*.fetch)
local remote="${prev#remote.}"
remote="${remote%.fetch}"
__gitcomp "$(__git_refs_remotes "$remote")"
if [ -z "$cur" ]; then
COMPREPLY=("refs/heads/")
return
fi
__gitcomp_nl "$(__git_refs_remotes "$remote")"
return
;;
remote.*.push)
local remote="${prev#remote.}"
remote="${remote%.push}"
__gitcomp "$(git --git-dir="$(__gitdir)" \
__gitcomp_nl "$(git --git-dir="$(__gitdir)" \
for-each-ref --format='%(refname):%(refname)' \
refs/heads)"
return
@ -1925,7 +1944,7 @@ _git_config () @@ -1925,7 +1944,7 @@ _git_config ()
return
;;
--get|--get-all|--unset|--unset-all)
__gitcomp "$(__git_config_get_set_variables)"
__gitcomp_nl "$(__git_config_get_set_variables)"
return
;;
*.*)
@ -1951,7 +1970,7 @@ _git_config () @@ -1951,7 +1970,7 @@ _git_config ()
;;
branch.*)
local pfx="${cur%.*}." cur_="${cur#*.}"
__gitcomp "$(__git_heads)" "$pfx" "$cur_" "."
__gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
return
;;
guitool.*.*)
@ -1980,7 +1999,7 @@ _git_config () @@ -1980,7 +1999,7 @@ _git_config ()
pager.*)
local pfx="${cur%.*}." cur_="${cur#*.}"
__git_compute_all_commands
__gitcomp "$__git_all_commands" "$pfx" "$cur_"
__gitcomp_nl "$__git_all_commands" "$pfx" "$cur_"
return
;;
remote.*.*)
@ -1993,7 +2012,7 @@ _git_config () @@ -1993,7 +2012,7 @@ _git_config ()
;;
remote.*)
local pfx="${cur%.*}." cur_="${cur#*.}"
__gitcomp "$(__git_remotes)" "$pfx" "$cur_" "."
__gitcomp_nl "$(__git_remotes)" "$pfx" "$cur_" "."
return
;;
url.*.*)
@ -2294,7 +2313,7 @@ _git_remote () @@ -2294,7 +2313,7 @@ _git_remote ()

case "$subcommand" in
rename|rm|show|prune)
__gitcomp "$(__git_remotes)"
__gitcomp_nl "$(__git_remotes)"
;;
update)
local i c='' IFS=$'\n'
@ -2312,7 +2331,7 @@ _git_remote () @@ -2312,7 +2331,7 @@ _git_remote ()

_git_replace ()
{
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
}

_git_reset ()
@ -2325,7 +2344,7 @@ _git_reset () @@ -2325,7 +2344,7 @@ _git_reset ()
return
;;
esac
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
}

_git_revert ()
@ -2336,7 +2355,7 @@ _git_revert () @@ -2336,7 +2355,7 @@ _git_revert ()
return
;;
esac
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
}

_git_rm ()
@ -2435,7 +2454,7 @@ _git_stash () @@ -2435,7 +2454,7 @@ _git_stash ()
COMPREPLY=()
;;
show,*|apply,*|drop,*|pop,*|branch,*)
__gitcomp "$(git --git-dir="$(__gitdir)" stash list \
__gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \
| sed -n -e 's/:.*//p')"
;;
*)
@ -2569,7 +2588,7 @@ _git_tag () @@ -2569,7 +2588,7 @@ _git_tag ()
i="${words[c]}"
case "$i" in
-d|-v)
__gitcomp "$(__git_tags)"
__gitcomp_nl "$(__git_tags)"
return
;;
-f)
@ -2585,13 +2604,13 @@ _git_tag () @@ -2585,13 +2604,13 @@ _git_tag ()
;;
-*|tag)
if [ $f = 1 ]; then
__gitcomp "$(__git_tags)"
__gitcomp_nl "$(__git_tags)"
else
COMPREPLY=()
fi
;;
*)
__gitcomp "$(__git_refs)"
__gitcomp_nl "$(__git_refs)"
;;
esac
}

Loading…
Cancel
Save