|
|
|
@ -301,6 +301,19 @@ __gitcomp_direct ()
@@ -301,6 +301,19 @@ __gitcomp_direct ()
|
|
|
|
|
COMPREPLY=($1) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Similar to __gitcomp_direct, but appends to COMPREPLY instead. |
|
|
|
|
# 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_append () |
|
|
|
|
{ |
|
|
|
|
local IFS=$'\n' |
|
|
|
|
|
|
|
|
|
COMPREPLY+=($1) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
__gitcompappend () |
|
|
|
|
{ |
|
|
|
|
local x i=${#COMPREPLY[@]} |
|
|
|
@ -611,6 +624,19 @@ __git_heads ()
@@ -611,6 +624,19 @@ __git_heads ()
|
|
|
|
|
"refs/heads/$cur_*" "refs/heads/$cur_*/**" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Lists branches from remote repositories. |
|
|
|
|
# 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_remote_heads () |
|
|
|
|
{ |
|
|
|
|
local pfx="${1-}" cur_="${2-}" sfx="${3-}" |
|
|
|
|
|
|
|
|
|
__git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \ |
|
|
|
|
"refs/remotes/$cur_*" "refs/remotes/$cur_*/**" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Lists tags from the local repository. |
|
|
|
|
# Accepts the same positional parameters as __git_heads() above. |
|
|
|
|
__git_tags () |
|
|
|
@ -621,6 +647,26 @@ __git_tags ()
@@ -621,6 +647,26 @@ __git_tags ()
|
|
|
|
|
"refs/tags/$cur_*" "refs/tags/$cur_*/**" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# List unique branches from refs/remotes used for 'git checkout' and 'git |
|
|
|
|
# switch' tracking DWIMery. |
|
|
|
|
# 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_dwim_remote_heads () |
|
|
|
|
{ |
|
|
|
|
local pfx="${1-}" cur_="${2-}" sfx="${3-}" |
|
|
|
|
local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers |
|
|
|
|
|
|
|
|
|
# employ the heuristic used by git checkout and git switch |
|
|
|
|
# Try to find a remote branch that cur_es the completion word |
|
|
|
|
# but only output if the branch name is unique |
|
|
|
|
__git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \ |
|
|
|
|
--sort="refname:strip=3" \ |
|
|
|
|
"refs/remotes/*/$cur_*" "refs/remotes/*/$cur_*/**" | \ |
|
|
|
|
uniq -u |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# 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). |
|
|
|
@ -696,13 +742,7 @@ __git_refs ()
@@ -696,13 +742,7 @@ __git_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 |
|
|
|
|
__git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \ |
|
|
|
|
--sort="refname:strip=3" \ |
|
|
|
|
"refs/remotes/*/$match*" "refs/remotes/*/$match*/**" | \ |
|
|
|
|
uniq -u |
|
|
|
|
__git_dwim_remote_heads "$pfx" "$match" "$sfx" |
|
|
|
|
fi |
|
|
|
|
return |
|
|
|
|
fi |
|
|
|
@ -749,29 +789,51 @@ __git_refs ()
@@ -749,29 +789,51 @@ __git_refs ()
|
|
|
|
|
# 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. |
|
|
|
|
# --dwim: List unique remote branches for 'git switch'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. |
|
|
|
|
# --mode=<mode>: What set of refs to complete, one of 'refs' (the default) to |
|
|
|
|
# complete all refs, 'heads' to complete only branches, or |
|
|
|
|
# 'remote-heads' to complete only remote branches. Note that |
|
|
|
|
# --remote is only compatible with --mode=refs. |
|
|
|
|
__git_complete_refs () |
|
|
|
|
{ |
|
|
|
|
local remote track pfx cur_="$cur" sfx=" " |
|
|
|
|
local remote dwim pfx cur_="$cur" sfx=" " mode="refs" |
|
|
|
|
|
|
|
|
|
while test $# != 0; do |
|
|
|
|
case "$1" in |
|
|
|
|
--remote=*) remote="${1##--remote=}" ;; |
|
|
|
|
--track) track="yes" ;; |
|
|
|
|
--dwim) dwim="yes" ;; |
|
|
|
|
# --track is an old spelling of --dwim |
|
|
|
|
--track) dwim="yes" ;; |
|
|
|
|
--pfx=*) pfx="${1##--pfx=}" ;; |
|
|
|
|
--cur=*) cur_="${1##--cur=}" ;; |
|
|
|
|
--sfx=*) sfx="${1##--sfx=}" ;; |
|
|
|
|
--mode=*) mode="${1##--mode=}" ;; |
|
|
|
|
*) return 1 ;; |
|
|
|
|
esac |
|
|
|
|
shift |
|
|
|
|
done |
|
|
|
|
|
|
|
|
|
__gitcomp_direct "$(__git_refs "$remote" "$track" "$pfx" "$cur_" "$sfx")" |
|
|
|
|
# complete references based on the specified mode |
|
|
|
|
case "$mode" in |
|
|
|
|
refs) |
|
|
|
|
__gitcomp_direct "$(__git_refs "$remote" "" "$pfx" "$cur_" "$sfx")" ;; |
|
|
|
|
heads) |
|
|
|
|
__gitcomp_direct "$(__git_heads "$pfx" "$cur_" "$sfx")" ;; |
|
|
|
|
remote-heads) |
|
|
|
|
__gitcomp_direct "$(__git_remote_heads "$pfx" "$cur_" "$sfx")" ;; |
|
|
|
|
*) |
|
|
|
|
return 1 ;; |
|
|
|
|
esac |
|
|
|
|
|
|
|
|
|
# Append DWIM remote branch names if requested |
|
|
|
|
if [ "$dwim" = "yes" ]; then |
|
|
|
|
__gitcomp_direct_append "$(__git_dwim_remote_heads "$pfx" "$cur_" "$sfx")" |
|
|
|
|
fi |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# __git_refs2 requires 1 argument (to pass to __git_refs) |
|
|
|
@ -1102,6 +1164,40 @@ __git_find_on_cmdline ()
@@ -1102,6 +1164,40 @@ __git_find_on_cmdline ()
|
|
|
|
|
done |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Similar to __git_find_on_cmdline, except that it loops backwards and thus |
|
|
|
|
# prints the *last* word found. Useful for finding which of two options that |
|
|
|
|
# supersede each other came last, such as "--guess" and "--no-guess". |
|
|
|
|
# |
|
|
|
|
# Usage: __git_find_last_on_cmdline [<option>]... "<wordlist>" |
|
|
|
|
# --show-idx: Optionally show the index of the found word in the $words array. |
|
|
|
|
__git_find_last_on_cmdline () |
|
|
|
|
{ |
|
|
|
|
local word c=$cword show_idx |
|
|
|
|
|
|
|
|
|
while test $# -gt 1; do |
|
|
|
|
case "$1" in |
|
|
|
|
--show-idx) show_idx=y ;; |
|
|
|
|
*) return 1 ;; |
|
|
|
|
esac |
|
|
|
|
shift |
|
|
|
|
done |
|
|
|
|
local wordlist="$1" |
|
|
|
|
|
|
|
|
|
while [ $c -gt 1 ]; do |
|
|
|
|
((c--)) |
|
|
|
|
for word in $wordlist; do |
|
|
|
|
if [ "$word" = "${words[c]}" ]; then |
|
|
|
|
if [ -n "$show_idx" ]; then |
|
|
|
|
echo "$c $word" |
|
|
|
|
else |
|
|
|
|
echo "$word" |
|
|
|
|
fi |
|
|
|
|
return |
|
|
|
|
fi |
|
|
|
|
done |
|
|
|
|
done |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Echo the value of an option set on the command line or config |
|
|
|
|
# |
|
|
|
|
# $1: short option name |
|
|
|
@ -1356,6 +1452,46 @@ _git_bundle ()
@@ -1356,6 +1452,46 @@ _git_bundle ()
|
|
|
|
|
esac |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
# Helper function to decide whether or not we should enable DWIM logic for |
|
|
|
|
# git-switch and git-checkout. |
|
|
|
|
# |
|
|
|
|
# To decide between the following rules in priority order |
|
|
|
|
# 1) the last provided of "--guess" or "--no-guess" explicitly enable or |
|
|
|
|
# disable completion of DWIM logic respectively. |
|
|
|
|
# 2) If the --no-track option is provided, take this as a hint to disable the |
|
|
|
|
# DWIM completion logic |
|
|
|
|
# 3) If GIT_COMPLETION_CHECKOUT_NO_GUESS is set, disable the DWIM completion |
|
|
|
|
# logic, as requested by the user. |
|
|
|
|
# 4) Enable DWIM logic otherwise. |
|
|
|
|
# |
|
|
|
|
__git_checkout_default_dwim_mode () |
|
|
|
|
{ |
|
|
|
|
local last_option dwim_opt="--dwim" |
|
|
|
|
|
|
|
|
|
if [ "$GIT_COMPLETION_CHECKOUT_NO_GUESS" = "1" ]; then |
|
|
|
|
dwim_opt="" |
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
# --no-track disables DWIM, but with lower priority than |
|
|
|
|
# --guess/--no-guess |
|
|
|
|
if [ -n "$(__git_find_on_cmdline "--no-track")" ]; then |
|
|
|
|
dwim_opt="" |
|
|
|
|
fi |
|
|
|
|
|
|
|
|
|
# Find the last provided --guess or --no-guess |
|
|
|
|
last_option="$(__git_find_last_on_cmdline "--guess --no-guess")" |
|
|
|
|
case "$last_option" in |
|
|
|
|
--guess) |
|
|
|
|
dwim_opt="--dwim" |
|
|
|
|
;; |
|
|
|
|
--no-guess) |
|
|
|
|
dwim_opt="" |
|
|
|
|
;; |
|
|
|
|
esac |
|
|
|
|
|
|
|
|
|
echo "$dwim_opt" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_git_checkout () |
|
|
|
|
{ |
|
|
|
|
__git_has_doubledash && return |
|
|
|
@ -1368,14 +1504,38 @@ _git_checkout ()
@@ -1368,14 +1504,38 @@ _git_checkout ()
|
|
|
|
|
__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_opt="--track" |
|
|
|
|
if [ "$GIT_COMPLETION_CHECKOUT_NO_GUESS" = "1" ] || |
|
|
|
|
[ -n "$(__git_find_on_cmdline "$flags")" ]; then |
|
|
|
|
track_opt='' |
|
|
|
|
local dwim_opt="$(__git_checkout_default_dwim_mode)" |
|
|
|
|
local prevword prevword="${words[cword-1]}" |
|
|
|
|
|
|
|
|
|
case "$prevword" in |
|
|
|
|
-b|-B|--orphan) |
|
|
|
|
# Complete local branches (and DWIM branch |
|
|
|
|
# remote branch names) for an option argument |
|
|
|
|
# specifying a new branch name. This is for |
|
|
|
|
# convenience, assuming new branches are |
|
|
|
|
# possibly based on pre-existing branch names. |
|
|
|
|
__git_complete_refs $dwim_opt --mode="heads" |
|
|
|
|
return |
|
|
|
|
;; |
|
|
|
|
*) |
|
|
|
|
;; |
|
|
|
|
esac |
|
|
|
|
|
|
|
|
|
# At this point, we've already handled special completion for |
|
|
|
|
# the arguments to -b/-B, and --orphan. There are 3 main |
|
|
|
|
# things left we can possibly complete: |
|
|
|
|
# 1) a start-point for -b/-B, -d/--detach, or --orphan |
|
|
|
|
# 2) a remote head, for --track |
|
|
|
|
# 3) an arbitrary reference, possibly including DWIM names |
|
|
|
|
# |
|
|
|
|
|
|
|
|
|
if [ -n "$(__git_find_on_cmdline "-b -B -d --detach --orphan")" ]; then |
|
|
|
|
__git_complete_refs --mode="refs" |
|
|
|
|
elif [ -n "$(__git_find_on_cmdline "--track")" ]; then |
|
|
|
|
__git_complete_refs --mode="remote-heads" |
|
|
|
|
else |
|
|
|
|
__git_complete_refs $dwim_opt --mode="refs" |
|
|
|
|
fi |
|
|
|
|
__git_complete_refs $track_opt |
|
|
|
|
;; |
|
|
|
|
esac |
|
|
|
|
} |
|
|
|
@ -2224,29 +2384,43 @@ _git_switch ()
@@ -2224,29 +2384,43 @@ _git_switch ()
|
|
|
|
|
__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= |
|
|
|
|
local dwim_opt="$(__git_checkout_default_dwim_mode)" |
|
|
|
|
local prevword prevword="${words[cword-1]}" |
|
|
|
|
|
|
|
|
|
case "$prevword" in |
|
|
|
|
-c|-C|--orphan) |
|
|
|
|
# Complete local branches (and DWIM branch |
|
|
|
|
# remote branch names) for an option argument |
|
|
|
|
# specifying a new branch name. This is for |
|
|
|
|
# convenience, assuming new branches are |
|
|
|
|
# possibly based on pre-existing branch names. |
|
|
|
|
__git_complete_refs $dwim_opt --mode="heads" |
|
|
|
|
return |
|
|
|
|
;; |
|
|
|
|
*) |
|
|
|
|
;; |
|
|
|
|
esac |
|
|
|
|
|
|
|
|
|
# Unlike in git checkout, git switch --orphan does not take |
|
|
|
|
# a start point. Thus we really have nothing to complete after |
|
|
|
|
# the branch name. |
|
|
|
|
if [ -n "$(__git_find_on_cmdline "--orphan")" ]; then |
|
|
|
|
return |
|
|
|
|
fi |
|
|
|
|
if [ $only_local_ref = y -a -z "$track_opt" ]; then |
|
|
|
|
__gitcomp_direct "$(__git_heads "" "$cur" " ")" |
|
|
|
|
|
|
|
|
|
# At this point, we've already handled special completion for |
|
|
|
|
# -c/-C, and --orphan. There are 3 main things left to |
|
|
|
|
# complete: |
|
|
|
|
# 1) a start-point for -c/-C or -d/--detach |
|
|
|
|
# 2) a remote head, for --track |
|
|
|
|
# 3) a branch name, possibly including DWIM remote branches |
|
|
|
|
|
|
|
|
|
if [ -n "$(__git_find_on_cmdline "-c -C -d --detach")" ]; then |
|
|
|
|
__git_complete_refs --mode="refs" |
|
|
|
|
elif [ -n "$(__git_find_on_cmdline "--track")" ]; then |
|
|
|
|
__git_complete_refs --mode="remote-heads" |
|
|
|
|
else |
|
|
|
|
__git_complete_refs $track_opt |
|
|
|
|
__git_complete_refs $dwim_opt --mode="heads" |
|
|
|
|
fi |
|
|
|
|
;; |
|
|
|
|
esac |
|
|
|
|