From: Cornelius Weig <cornelius.weig@xxxxxxxxxxx> Git-checkout completes words starting with '--' as options and other words as refs. Even after specifying a ref, further words not starting with '--' are completed as refs, which is invalid for git-checkout. This commit ensures that after specifying a ref, further non-option words are completed as paths. Four cases are considered: - If the word contains a ':', do not treat it as reference and use regular revlist completion. - If no ref is found on the command line, complete non-options as refs as before. - If the ref is HEAD or @, complete only with modified files because checking out unmodified files is a noop. This case also applies if no ref is given, but '--' is present. - If a ref other than HEAD or @ is found, offer only valid paths from that revision. Note that one corner-case is not covered by the current implementation: if a refname contains a ':' and is followed by '--' the completion would not recognize the valid refname. Signed-off-by: Cornelius Weig <cornelius.weig@xxxxxxxxxxx> --- contrib/completion/git-completion.bash | 39 +++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 4ab119d..df46f62 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -1068,7 +1068,7 @@ _git_bundle () _git_checkout () { - __git_has_doubledash && return + local i c=2 ref="" seen_double_dash="" case "$cur" in --conflict=*) @@ -1081,13 +1081,36 @@ _git_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='' - fi - __gitcomp_nl "$(__git_refs '' $track)" + while [ $c -lt $cword ]; do + i="${words[c]}" + case "$i" in + --) seen_double_dash=1 ;; + -*|?*:*) ;; + *) ref="$i"; break ;; + esac + ((c++)) + done + + case "$ref,$seen_double_dash,$cur" in + ,,*:*) + __git_complete_revlist_file + ;; + ,,*) + # check for --track, --no-track, or --no-guess + # if so, disable DWIM mode + local flags="--track --no-track --no-guess" track=1 + if [ -n "$(__git_find_on_cmdline "$flags")" ]; then + track='' + fi + __gitcomp_nl "$(__git_refs '' $track)" + ;; + ,1,*|@,*|HEAD,*) + __git_complete_index_file "--modified" + ;; + *) + __git_complete_tree_file "$ref" "$cur" + ;; + esac ;; esac } -- 2.10.2