2012-04-11 23:57:03 +02:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (c) 2012 Felipe Contreras
|
|
|
|
#
|
|
|
|
|
|
|
|
test_description='test bash completion'
|
|
|
|
|
2012-05-09 02:44:32 +02:00
|
|
|
. ./lib-bash.sh
|
2012-04-11 23:57:03 +02:00
|
|
|
|
|
|
|
complete ()
|
|
|
|
{
|
|
|
|
# do nothing
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2013-01-25 00:08:37 +01:00
|
|
|
# Be careful when updating this list:
|
|
|
|
#
|
|
|
|
# (1) The build tree may have build artifact from different branch, or
|
|
|
|
# the user's $PATH may have a random executable that may begin
|
|
|
|
# with "git-check" that are not part of the subcommands this build
|
|
|
|
# will ship, e.g. "check-ignore". The tests for completion for
|
|
|
|
# subcommand names tests how "check" is expanded; we limit the
|
|
|
|
# possible candidates to "checkout" and "check-attr" to make sure
|
|
|
|
# "check-attr", which is known by the filter function as a
|
|
|
|
# subcommand to be thrown out, while excluding other random files
|
|
|
|
# that happen to begin with "check" to avoid letting them get in
|
|
|
|
# the way.
|
|
|
|
#
|
|
|
|
# (2) A test makes sure that common subcommands are included in the
|
|
|
|
# completion for "git <TAB>", and a plumbing is excluded. "add",
|
|
|
|
# "filter-branch" and "ls-files" are listed for this.
|
|
|
|
|
|
|
|
GIT_TESTING_COMMAND_COMPLETION='add checkout check-attr filter-branch ls-files'
|
|
|
|
|
2012-04-11 23:57:03 +02:00
|
|
|
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
|
|
|
|
|
|
|
|
# We don't need this function to actually join words or do anything special.
|
|
|
|
# Also, it's cleaner to avoid touching bash's internal completion variables.
|
|
|
|
# So let's override it with a minimal version for testing purposes.
|
|
|
|
_get_comp_words_by_ref ()
|
|
|
|
{
|
|
|
|
while [ $# -gt 0 ]; do
|
|
|
|
case "$1" in
|
|
|
|
cur)
|
|
|
|
cur=${_words[_cword]}
|
|
|
|
;;
|
|
|
|
prev)
|
|
|
|
prev=${_words[_cword-1]}
|
|
|
|
;;
|
|
|
|
words)
|
|
|
|
words=("${_words[@]}")
|
|
|
|
;;
|
|
|
|
cword)
|
|
|
|
cword=$_cword
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
print_comp ()
|
|
|
|
{
|
|
|
|
local IFS=$'\n'
|
|
|
|
echo "${COMPREPLY[*]}" > out
|
|
|
|
}
|
|
|
|
|
|
|
|
run_completion ()
|
|
|
|
{
|
|
|
|
local -a COMPREPLY _words
|
|
|
|
local _cword
|
|
|
|
_words=( $1 )
|
|
|
|
(( _cword = ${#_words[@]} - 1 ))
|
2012-06-13 10:08:50 +02:00
|
|
|
__git_wrap__git_main && print_comp
|
2012-04-11 23:57:03 +02:00
|
|
|
}
|
|
|
|
|
2012-11-11 15:35:53 +01:00
|
|
|
# Test high-level completion
|
|
|
|
# Arguments are:
|
|
|
|
# 1: typed text so far (cur)
|
|
|
|
# 2: expected completion
|
2012-04-11 23:57:03 +02:00
|
|
|
test_completion ()
|
|
|
|
{
|
2012-11-11 15:35:56 +01:00
|
|
|
if test $# -gt 1
|
|
|
|
then
|
|
|
|
printf '%s\n' "$2" >expected
|
|
|
|
else
|
|
|
|
sed -e 's/Z$//' >expected
|
|
|
|
fi &&
|
2012-11-11 15:35:53 +01:00
|
|
|
run_completion "$1" &&
|
2012-04-11 23:57:03 +02:00
|
|
|
test_cmp expected out
|
|
|
|
}
|
|
|
|
|
2012-11-11 15:35:57 +01:00
|
|
|
# Test __gitcomp.
|
|
|
|
# The first argument is the typed text so far (cur); the rest are
|
|
|
|
# passed to __gitcomp. Expected output comes is read from the
|
|
|
|
# standard input, like test_completion().
|
|
|
|
test_gitcomp ()
|
2012-09-26 23:47:51 +02:00
|
|
|
{
|
2012-11-11 15:35:58 +01:00
|
|
|
local -a COMPREPLY &&
|
2012-11-11 15:35:57 +01:00
|
|
|
sed -e 's/Z$//' >expected &&
|
2012-11-11 15:35:58 +01:00
|
|
|
cur="$1" &&
|
|
|
|
shift &&
|
|
|
|
__gitcomp "$@" &&
|
|
|
|
print_comp &&
|
2012-04-17 12:27:15 +02:00
|
|
|
test_cmp expected out
|
2012-09-26 23:47:51 +02:00
|
|
|
}
|
|
|
|
|
2012-04-17 12:27:15 +02:00
|
|
|
test_expect_success '__gitcomp - trailing space - options' '
|
2012-11-11 15:35:57 +01:00
|
|
|
test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
|
|
|
|
--reset-author" <<-EOF
|
2012-04-17 12:27:15 +02:00
|
|
|
--reuse-message=Z
|
|
|
|
--reedit-message=Z
|
|
|
|
--reset-author Z
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp - trailing space - config keys' '
|
2012-11-11 15:35:57 +01:00
|
|
|
test_gitcomp "br" "branch. branch.autosetupmerge
|
|
|
|
branch.autosetuprebase browser." <<-\EOF
|
2012-04-17 12:27:15 +02:00
|
|
|
branch.Z
|
|
|
|
branch.autosetupmerge Z
|
|
|
|
branch.autosetuprebase Z
|
|
|
|
browser.Z
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp - option parameter' '
|
2012-11-11 15:35:57 +01:00
|
|
|
test_gitcomp "--strategy=re" "octopus ours recursive resolve subtree" \
|
|
|
|
"" "re" <<-\EOF
|
2012-04-17 12:27:15 +02:00
|
|
|
recursive Z
|
|
|
|
resolve Z
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp - prefix' '
|
2012-11-11 15:35:57 +01:00
|
|
|
test_gitcomp "branch.me" "remote merge mergeoptions rebase" \
|
|
|
|
"branch.maint." "me" <<-\EOF
|
2012-04-17 12:27:15 +02:00
|
|
|
branch.maint.merge Z
|
|
|
|
branch.maint.mergeoptions Z
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp - suffix' '
|
2012-11-11 15:35:57 +01:00
|
|
|
test_gitcomp "branch.me" "master maint next pu" "branch." \
|
|
|
|
"ma" "." <<-\EOF
|
2012-04-17 12:27:15 +02:00
|
|
|
branch.master.Z
|
|
|
|
branch.maint.Z
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
2012-04-11 23:57:03 +02:00
|
|
|
test_expect_success 'basic' '
|
|
|
|
run_completion "git \"\"" &&
|
|
|
|
# built-in
|
|
|
|
grep -q "^add \$" out &&
|
|
|
|
# script
|
|
|
|
grep -q "^filter-branch \$" out &&
|
|
|
|
# plumbing
|
|
|
|
! grep -q "^ls-files \$" out &&
|
|
|
|
|
|
|
|
run_completion "git f" &&
|
|
|
|
! grep -q -v "^f" out
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'double dash "git" itself' '
|
2012-11-11 15:35:56 +01:00
|
|
|
test_completion "git --" <<-\EOF
|
2012-04-11 23:57:03 +02:00
|
|
|
--paginate Z
|
|
|
|
--no-pager Z
|
|
|
|
--git-dir=
|
|
|
|
--bare Z
|
|
|
|
--version Z
|
|
|
|
--exec-path Z
|
2012-04-15 21:44:19 +02:00
|
|
|
--exec-path=
|
2012-04-11 23:57:03 +02:00
|
|
|
--html-path Z
|
2012-04-15 21:44:18 +02:00
|
|
|
--info-path Z
|
2012-04-11 23:57:03 +02:00
|
|
|
--work-tree=
|
|
|
|
--namespace=
|
2012-04-15 21:44:18 +02:00
|
|
|
--no-replace-objects Z
|
2012-04-11 23:57:03 +02:00
|
|
|
--help Z
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'double dash "git checkout"' '
|
2012-11-11 15:35:56 +01:00
|
|
|
test_completion "git checkout --" <<-\EOF
|
2012-04-11 23:57:03 +02:00
|
|
|
--quiet Z
|
|
|
|
--ours Z
|
|
|
|
--theirs Z
|
|
|
|
--track Z
|
|
|
|
--no-track Z
|
|
|
|
--merge Z
|
|
|
|
--conflict=
|
|
|
|
--orphan Z
|
|
|
|
--patch Z
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
2012-04-15 21:44:18 +02:00
|
|
|
test_expect_success 'general options' '
|
|
|
|
test_completion "git --ver" "--version " &&
|
|
|
|
test_completion "git --hel" "--help " &&
|
2012-11-11 15:35:56 +01:00
|
|
|
test_completion "git --exe" <<-\EOF &&
|
2012-04-15 21:44:19 +02:00
|
|
|
--exec-path Z
|
|
|
|
--exec-path=
|
|
|
|
EOF
|
2012-04-15 21:44:18 +02:00
|
|
|
test_completion "git --htm" "--html-path " &&
|
|
|
|
test_completion "git --pag" "--paginate " &&
|
|
|
|
test_completion "git --no-p" "--no-pager " &&
|
|
|
|
test_completion "git --git" "--git-dir=" &&
|
|
|
|
test_completion "git --wor" "--work-tree=" &&
|
|
|
|
test_completion "git --nam" "--namespace=" &&
|
|
|
|
test_completion "git --bar" "--bare " &&
|
|
|
|
test_completion "git --inf" "--info-path " &&
|
|
|
|
test_completion "git --no-r" "--no-replace-objects "
|
|
|
|
'
|
completion: fix completion after 'git --option <TAB>'
The bash completion doesn't work when certain options to git itself are
specified, e.g. 'git --no-pager <TAB>' errors out with
error: invalid key: alias.--no-pager
The main _git() completion function finds out the git command name by
looping through all the words on the command line and searching for
the first word that is not a known option for the git command.
Unfortunately the list of known git options was not updated in a long
time, and newer options are not skipped but mistaken for a git command.
Such a misrecognized "command" is then passed to __git_aliased_command(),
which in turn passes it to a 'git config' query, hence the error.
Currently the following options are misrecognized for a git command:
-c --no-pager --exec-path --html-path --man-path --info-path
--no-replace-objects --work-tree= --namespace=
To fix this we could just update the list of options to be skipped,
but the same issue will likely arise, if the git command learns a new
option in the future. Therefore, to make it more future proof against
new options, this patch changes that loop to skip all option-looking
words, i.e. words starting with a dash.
We also have to handle the '-c' option specially, because it takes a
configutation parameter in a separate word, which must be skipped,
too.
[fc: added tests]
Signed-off-by: SZEDER Gábor <szeder@ira.uka.de>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-15 21:44:20 +02:00
|
|
|
|
|
|
|
test_expect_success 'general options plus command' '
|
|
|
|
test_completion "git --version check" "checkout " &&
|
|
|
|
test_completion "git --paginate check" "checkout " &&
|
|
|
|
test_completion "git --git-dir=foo check" "checkout " &&
|
|
|
|
test_completion "git --bare check" "checkout " &&
|
|
|
|
test_completion "git --exec-path=foo check" "checkout " &&
|
|
|
|
test_completion "git --html-path check" "checkout " &&
|
|
|
|
test_completion "git --no-pager check" "checkout " &&
|
|
|
|
test_completion "git --work-tree=foo check" "checkout " &&
|
|
|
|
test_completion "git --namespace=foo check" "checkout " &&
|
|
|
|
test_completion "git --paginate check" "checkout " &&
|
|
|
|
test_completion "git --info-path check" "checkout " &&
|
|
|
|
test_completion "git --no-replace-objects check" "checkout "
|
|
|
|
'
|
|
|
|
|
2013-01-25 00:08:37 +01:00
|
|
|
test_expect_success 'git --help completion' '
|
|
|
|
test_completion "git --help ad" "add " &&
|
|
|
|
test_completion "git --help core" "core-tutorial "
|
|
|
|
'
|
|
|
|
|
2012-09-26 23:47:51 +02:00
|
|
|
test_expect_success 'setup for ref completion' '
|
|
|
|
echo content >file1 &&
|
|
|
|
echo more >file2 &&
|
|
|
|
git add . &&
|
|
|
|
git commit -m one &&
|
|
|
|
git branch mybranch &&
|
|
|
|
git tag mytag
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'checkout completes ref names' '
|
2012-11-11 15:35:56 +01:00
|
|
|
test_completion "git checkout m" <<-\EOF
|
2012-11-11 15:35:54 +01:00
|
|
|
master Z
|
|
|
|
mybranch Z
|
|
|
|
mytag Z
|
2012-09-26 23:47:51 +02:00
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'show completes all refs' '
|
2012-11-11 15:35:56 +01:00
|
|
|
test_completion "git show m" <<-\EOF
|
2012-11-11 15:35:54 +01:00
|
|
|
master Z
|
|
|
|
mybranch Z
|
|
|
|
mytag Z
|
2012-09-26 23:47:51 +02:00
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '<ref>: completes paths' '
|
2012-11-11 15:35:56 +01:00
|
|
|
test_completion "git show mytag:f" <<-\EOF
|
2012-11-11 15:35:54 +01:00
|
|
|
file1 Z
|
|
|
|
file2 Z
|
2012-09-26 23:47:51 +02:00
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
2012-09-26 23:51:06 +02:00
|
|
|
test_expect_success 'complete tree filename with spaces' '
|
|
|
|
echo content >"name with spaces" &&
|
|
|
|
git add . &&
|
|
|
|
git commit -m spaces &&
|
2012-11-11 15:35:56 +01:00
|
|
|
test_completion "git show HEAD:nam" <<-\EOF
|
2012-11-11 15:35:54 +01:00
|
|
|
name with spaces Z
|
2012-09-26 23:51:06 +02:00
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_failure 'complete tree filename with metacharacters' '
|
|
|
|
echo content >"name with \${meta}" &&
|
|
|
|
git add . &&
|
|
|
|
git commit -m meta &&
|
2012-11-11 15:35:56 +01:00
|
|
|
test_completion "git show HEAD:nam" <<-\EOF
|
2012-11-11 15:35:54 +01:00
|
|
|
name with ${meta} Z
|
|
|
|
name with spaces Z
|
2012-09-26 23:51:06 +02:00
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
2012-10-16 02:21:50 +02:00
|
|
|
test_expect_success 'send-email' '
|
|
|
|
test_completion "git send-email --cov" "--cover-letter " &&
|
|
|
|
test_completion "git send-email ma" "master "
|
|
|
|
'
|
|
|
|
|
2012-04-11 23:57:03 +02:00
|
|
|
test_done
|