Skip to content

Commit b2714ff

Browse files
committed
Merge branch 'fc/completion-aliases-support' into next
Bash completion (in contrib/) update to make it easier for end-users to add completion for their custom "git" subcommands. * fc/completion-aliases-support: completion: add proper public __git_complete test: completion: add tests for __git_complete completion: bash: improve function detection completion: bash: add __git_have_func helper
2 parents cae5b73 + 5a067ba commit b2714ff

File tree

2 files changed

+60
-10
lines changed

2 files changed

+60
-10
lines changed

contrib/completion/git-completion.bash

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@
2929
# tell the completion to use commit completion. This also works with aliases
3030
# of form "!sh -c '...'". For example, "!sh -c ': git commit ; ... '".
3131
#
32+
# If you have a command that is not part of git, but you would still
33+
# like completion, you can use __git_complete:
34+
#
35+
# __git_complete gl git_log
36+
#
37+
# Or if it's a main command (i.e. git or gitk):
38+
#
39+
# __git_complete gk gitk
40+
#
3241
# Compatible with bash 3.2.57.
3342
#
3443
# You can set the following environment variables to influence the behavior of
@@ -3358,15 +3367,19 @@ __git_support_parseopt_helper () {
33583367
esac
33593368
}
33603369

3370+
__git_have_func () {
3371+
declare -f -- "$1" >/dev/null 2>&1
3372+
}
3373+
33613374
__git_complete_command () {
33623375
local command="$1"
33633376
local completion_func="_git_${command//-/_}"
3364-
if ! declare -f $completion_func >/dev/null 2>/dev/null &&
3365-
declare -f _completion_loader >/dev/null 2>/dev/null
3377+
if ! __git_have_func $completion_func &&
3378+
__git_have_func _completion_loader
33663379
then
33673380
_completion_loader "git-$command"
33683381
fi
3369-
if declare -f $completion_func >/dev/null 2>/dev/null
3382+
if __git_have_func $completion_func
33703383
then
33713384
$completion_func
33723385
return 0
@@ -3493,24 +3506,41 @@ __git_func_wrap ()
34933506
$1
34943507
}
34953508

3496-
# Setup completion for certain functions defined above by setting common
3497-
# variables and workarounds.
3498-
# This is NOT a public function; use at your own risk.
3499-
__git_complete ()
3509+
___git_complete ()
35003510
{
35013511
local wrapper="__git_wrap${2}"
35023512
eval "$wrapper () { __git_func_wrap $2 ; }"
35033513
complete -o bashdefault -o default -o nospace -F $wrapper $1 2>/dev/null \
35043514
|| complete -o default -o nospace -F $wrapper $1
35053515
}
35063516

3507-
__git_complete git __git_main
3508-
__git_complete gitk __gitk_main
3517+
# Setup the completion for git commands
3518+
# 1: command or alias
3519+
# 2: function to call (e.g. `git`, `gitk`, `git_fetch`)
3520+
__git_complete ()
3521+
{
3522+
local func
3523+
3524+
if __git_have_func $2; then
3525+
func=$2
3526+
elif __git_have_func __$2_main; then
3527+
func=__$2_main
3528+
elif __git_have_func _$2; then
3529+
func=_$2
3530+
else
3531+
echo "ERROR: could not find function '$2'" 1>&2
3532+
return 1
3533+
fi
3534+
___git_complete $1 $func
3535+
}
3536+
3537+
___git_complete git __git_main
3538+
___git_complete gitk __gitk_main
35093539

35103540
# The following are necessary only for Cygwin, and only are needed
35113541
# when the user has tab-completed the executable name and consequently
35123542
# included the '.exe' suffix.
35133543
#
35143544
if [ "$OSTYPE" = cygwin ]; then
3515-
__git_complete git.exe __git_main
3545+
___git_complete git.exe __git_main
35163546
fi

t/t9902-completion.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2380,4 +2380,24 @@ test_expect_success 'sourcing the completion script clears cached --options' '
23802380
verbose test -z "$__gitcomp_builtin_notes_edit"
23812381
'
23822382

2383+
test_expect_success '__git_complete' '
2384+
unset -f __git_wrap__git_main &&
2385+
2386+
__git_complete foo __git_main &&
2387+
__git_have_func __git_wrap__git_main &&
2388+
unset -f __git_wrap__git_main &&
2389+
2390+
__git_complete gf _git_fetch &&
2391+
__git_have_func __git_wrap_git_fetch &&
2392+
2393+
__git_complete foo git &&
2394+
__git_have_func __git_wrap__git_main &&
2395+
unset -f __git_wrap__git_main &&
2396+
2397+
__git_complete gd git_diff &&
2398+
__git_have_func __git_wrap_git_diff &&
2399+
2400+
test_must_fail __git_complete ga missing
2401+
'
2402+
23832403
test_done

0 commit comments

Comments
 (0)