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
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-20 20:40:04 +02:00
|
|
|
|
# Be careful when updating these lists:
|
2013-01-25 00:08:37 +01:00
|
|
|
|
#
|
|
|
|
|
# (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.
|
|
|
|
|
|
2018-05-20 20:40:04 +02:00
|
|
|
|
GIT_TESTING_ALL_COMMAND_LIST='add checkout check-attr filter-branch ls-files'
|
|
|
|
|
GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout filter-branch'
|
2013-01-25 00:08:37 +01:00
|
|
|
|
|
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 )
|
2013-08-21 22:49:32 +02:00
|
|
|
|
test "${1: -1}" = ' ' && _words[${#_words[@]}+1]=''
|
2012-04-11 23:57:03 +02:00
|
|
|
|
(( _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
|
t9902-completion: ignore COMPREPLY element order in some tests
The order or possible completion words in the COMPREPLY array doesn't
actually matter, as long as all the right words are in there, because
Bash will sort them anyway. Yet, our tests looking at the elements of
COMPREPLY always expect them to be in a specific order.
Now, this hasn't been an issue before, but the next patch is about to
optimize a bit more our git-aware path completion, and as a harmless
side effect the order of elements in COMPREPLY will change. Worse,
the order will be downright undefined, because after the next patch
path components will come directly from iterating through an
associative array in 'awk', and the order of iteration over the
elements in those arrays is undefined, and indeed different 'awk'
implementations produce different order. Consequently, we can't get
away with simply adjusting the expected results in the affected tests.
Modify the 'test_completion' helper function to sort both the expected
and the actual results, i.e. the elements in COMPREPLY, before
comparing them, so the tests using this helper function will work
regardless of the order of elements.
Note that this change still leaves a bunch of tests depending on the
order of elements in COMPREPLY, tests that focus on a specific helper
function and therefore don't use the 'test_completion' helper. I
would rather deal with those later, when (if ever) the need actually
arises, than create unnecessary code churn now.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-17 00:41:12 +02:00
|
|
|
|
sed -e 's/Z$//' |sort >expected
|
2012-11-11 15:35:56 +01:00
|
|
|
|
fi &&
|
2012-11-11 15:35:53 +01:00
|
|
|
|
run_completion "$1" &&
|
t9902-completion: ignore COMPREPLY element order in some tests
The order or possible completion words in the COMPREPLY array doesn't
actually matter, as long as all the right words are in there, because
Bash will sort them anyway. Yet, our tests looking at the elements of
COMPREPLY always expect them to be in a specific order.
Now, this hasn't been an issue before, but the next patch is about to
optimize a bit more our git-aware path completion, and as a harmless
side effect the order of elements in COMPREPLY will change. Worse,
the order will be downright undefined, because after the next patch
path components will come directly from iterating through an
associative array in 'awk', and the order of iteration over the
elements in those arrays is undefined, and indeed different 'awk'
implementations produce different order. Consequently, we can't get
away with simply adjusting the expected results in the affected tests.
Modify the 'test_completion' helper function to sort both the expected
and the actual results, i.e. the elements in COMPREPLY, before
comparing them, so the tests using this helper function will work
regardless of the order of elements.
Note that this change still leaves a bunch of tests depending on the
order of elements in COMPREPLY, tests that focus on a specific helper
function and therefore don't use the 'test_completion' helper. I
would rather deal with those later, when (if ever) the need actually
arises, than create unnecessary code churn now.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-17 00:41:12 +02:00
|
|
|
|
sort out >out_sorted &&
|
|
|
|
|
test_cmp expected out_sorted
|
2012-04-11 23:57:03 +02:00
|
|
|
|
}
|
|
|
|
|
|
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 &&
|
2017-02-03 03:48:11 +01:00
|
|
|
|
local cur="$1" &&
|
2012-11-11 15:35:58 +01:00
|
|
|
|
shift &&
|
|
|
|
|
__gitcomp "$@" &&
|
|
|
|
|
print_comp &&
|
2012-04-17 12:27:15 +02:00
|
|
|
|
test_cmp expected out
|
2012-09-26 23:47:51 +02:00
|
|
|
|
}
|
|
|
|
|
|
2013-04-10 08:57:54 +02:00
|
|
|
|
# Test __gitcomp_nl
|
|
|
|
|
# Arguments are:
|
|
|
|
|
# 1: current word (cur)
|
|
|
|
|
# -: the rest are passed to __gitcomp_nl
|
|
|
|
|
test_gitcomp_nl ()
|
|
|
|
|
{
|
|
|
|
|
local -a COMPREPLY &&
|
|
|
|
|
sed -e 's/Z$//' >expected &&
|
2017-02-03 03:48:11 +01:00
|
|
|
|
local cur="$1" &&
|
2013-04-10 08:57:54 +02:00
|
|
|
|
shift &&
|
|
|
|
|
__gitcomp_nl "$@" &&
|
|
|
|
|
print_comp &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
invalid_variable_name='${foo.bar}'
|
|
|
|
|
|
2013-06-17 20:31:51 +02:00
|
|
|
|
actual="$TRASH_DIRECTORY/actual"
|
|
|
|
|
|
2017-02-03 03:48:12 +01:00
|
|
|
|
if test_have_prereq MINGW
|
|
|
|
|
then
|
|
|
|
|
ROOT="$(pwd -W)"
|
|
|
|
|
else
|
|
|
|
|
ROOT="$(pwd)"
|
|
|
|
|
fi
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success 'setup for __git_find_repo_path/__gitdir tests' '
|
2013-06-17 20:31:51 +02:00
|
|
|
|
mkdir -p subdir/subsubdir &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
mkdir -p non-repo &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
git init otherrepo
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - from command line (through $__git_dir)' '
|
2017-02-03 03:48:12 +01:00
|
|
|
|
echo "$ROOT/otherrepo/.git" >expected &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
(
|
2017-02-03 03:48:12 +01:00
|
|
|
|
__git_dir="$ROOT/otherrepo/.git" &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
2017-02-03 03:48:28 +01:00
|
|
|
|
) &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - .git directory in cwd' '
|
2013-06-17 20:31:51 +02:00
|
|
|
|
echo ".git" >expected &&
|
2017-02-03 03:48:28 +01:00
|
|
|
|
(
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
2017-02-03 03:48:28 +01:00
|
|
|
|
) &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - .git directory in parent' '
|
2017-02-03 03:48:12 +01:00
|
|
|
|
echo "$ROOT/.git" >expected &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
(
|
|
|
|
|
cd subdir/subsubdir &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
2013-06-17 20:31:51 +02:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - cwd is a .git directory' '
|
2013-06-17 20:31:51 +02:00
|
|
|
|
echo "." >expected &&
|
|
|
|
|
(
|
|
|
|
|
cd .git &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
2013-06-17 20:31:51 +02:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - parent is a .git directory' '
|
2017-02-03 03:48:12 +01:00
|
|
|
|
echo "$ROOT/.git" >expected &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
(
|
2018-05-26 08:47:45 +02:00
|
|
|
|
cd .git/objects &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
2013-06-17 20:31:51 +02:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - $GIT_DIR set while .git directory in cwd' '
|
2017-02-03 03:48:12 +01:00
|
|
|
|
echo "$ROOT/otherrepo/.git" >expected &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
(
|
2017-02-03 03:48:12 +01:00
|
|
|
|
GIT_DIR="$ROOT/otherrepo/.git" &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
export GIT_DIR &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
2013-06-17 20:31:51 +02:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - $GIT_DIR set while .git directory in parent' '
|
2017-02-03 03:48:12 +01:00
|
|
|
|
echo "$ROOT/otherrepo/.git" >expected &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
(
|
2017-02-03 03:48:12 +01:00
|
|
|
|
GIT_DIR="$ROOT/otherrepo/.git" &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
export GIT_DIR &&
|
|
|
|
|
cd subdir &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
2013-06-17 20:31:51 +02:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - from command line while "git -C"' '
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
echo "$ROOT/.git" >expected &&
|
|
|
|
|
(
|
|
|
|
|
__git_dir="$ROOT/.git" &&
|
|
|
|
|
__git_C_args=(-C otherrepo) &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - relative dir from command line and "git -C"' '
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
echo "$ROOT/otherrepo/.git" >expected &&
|
|
|
|
|
(
|
|
|
|
|
cd subdir &&
|
|
|
|
|
__git_dir="otherrepo/.git" &&
|
|
|
|
|
__git_C_args=(-C ..) &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - $GIT_DIR set while "git -C"' '
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
echo "$ROOT/.git" >expected &&
|
|
|
|
|
(
|
|
|
|
|
GIT_DIR="$ROOT/.git" &&
|
|
|
|
|
export GIT_DIR &&
|
|
|
|
|
__git_C_args=(-C otherrepo) &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - relative dir in $GIT_DIR and "git -C"' '
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
echo "$ROOT/otherrepo/.git" >expected &&
|
|
|
|
|
(
|
|
|
|
|
cd subdir &&
|
|
|
|
|
GIT_DIR="otherrepo/.git" &&
|
|
|
|
|
export GIT_DIR &&
|
|
|
|
|
__git_C_args=(-C ..) &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - "git -C" while .git directory in cwd' '
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
echo "$ROOT/otherrepo/.git" >expected &&
|
|
|
|
|
(
|
|
|
|
|
__git_C_args=(-C otherrepo) &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - "git -C" while cwd is a .git directory' '
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
echo "$ROOT/otherrepo/.git" >expected &&
|
|
|
|
|
(
|
|
|
|
|
cd .git &&
|
|
|
|
|
__git_C_args=(-C .. -C otherrepo) &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - "git -C" while .git directory in parent' '
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
echo "$ROOT/otherrepo/.git" >expected &&
|
|
|
|
|
(
|
|
|
|
|
cd subdir &&
|
|
|
|
|
__git_C_args=(-C .. -C otherrepo) &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - non-existing path in "git -C"' '
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
(
|
|
|
|
|
__git_C_args=(-C non-existing) &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_must_fail __git_find_repo_path &&
|
|
|
|
|
printf "$__git_repo_path" >"$actual"
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
) &&
|
|
|
|
|
test_must_be_empty "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - non-existing path in $__git_dir' '
|
2017-02-03 03:48:15 +01:00
|
|
|
|
(
|
|
|
|
|
__git_dir="non-existing" &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_must_fail __git_find_repo_path &&
|
|
|
|
|
printf "$__git_repo_path" >"$actual"
|
2017-02-03 03:48:15 +01:00
|
|
|
|
) &&
|
|
|
|
|
test_must_be_empty "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - non-existing $GIT_DIR' '
|
2013-06-17 20:31:51 +02:00
|
|
|
|
(
|
2017-02-03 03:48:12 +01:00
|
|
|
|
GIT_DIR="$ROOT/non-existing" &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
export GIT_DIR &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_must_fail __git_find_repo_path &&
|
|
|
|
|
printf "$__git_repo_path" >"$actual"
|
2017-02-03 03:48:13 +01:00
|
|
|
|
) &&
|
|
|
|
|
test_must_be_empty "$actual"
|
2013-06-17 20:31:51 +02:00
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - gitfile in cwd' '
|
2017-02-03 03:48:12 +01:00
|
|
|
|
echo "$ROOT/otherrepo/.git" >expected &&
|
|
|
|
|
echo "gitdir: $ROOT/otherrepo/.git" >subdir/.git &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
test_when_finished "rm -f subdir/.git" &&
|
|
|
|
|
(
|
|
|
|
|
cd subdir &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
2013-06-17 20:31:51 +02:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__git_find_repo_path - gitfile in parent' '
|
2017-02-03 03:48:12 +01:00
|
|
|
|
echo "$ROOT/otherrepo/.git" >expected &&
|
|
|
|
|
echo "gitdir: $ROOT/otherrepo/.git" >subdir/.git &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
test_when_finished "rm -f subdir/.git" &&
|
|
|
|
|
(
|
|
|
|
|
cd subdir/subsubdir &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
2013-06-17 20:31:51 +02:00
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success SYMLINKS '__git_find_repo_path - resulting path avoids symlinks' '
|
2017-02-03 03:48:12 +01:00
|
|
|
|
echo "$ROOT/otherrepo/.git" >expected &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
mkdir otherrepo/dir &&
|
|
|
|
|
test_when_finished "rm -rf otherrepo/dir" &&
|
|
|
|
|
ln -s otherrepo/dir link &&
|
|
|
|
|
test_when_finished "rm -f link" &&
|
|
|
|
|
(
|
|
|
|
|
cd link &&
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
__git_find_repo_path &&
|
|
|
|
|
echo "$__git_repo_path" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_find_repo_path - not a git repository' '
|
|
|
|
|
(
|
|
|
|
|
cd non-repo &&
|
|
|
|
|
GIT_CEILING_DIRECTORIES="$ROOT" &&
|
|
|
|
|
export GIT_CEILING_DIRECTORIES &&
|
|
|
|
|
test_must_fail __git_find_repo_path &&
|
|
|
|
|
printf "$__git_repo_path" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_must_be_empty "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__gitdir - finds repo' '
|
|
|
|
|
echo "$ROOT/.git" >expected &&
|
|
|
|
|
(
|
|
|
|
|
cd subdir/subsubdir &&
|
2013-06-17 20:31:51 +02:00
|
|
|
|
__gitdir >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
|
|
|
|
|
test_expect_success '__gitdir - returns error when cant find repo' '
|
|
|
|
|
(
|
|
|
|
|
__git_dir="non-existing" &&
|
|
|
|
|
test_must_fail __gitdir >"$actual"
|
|
|
|
|
) &&
|
2017-02-03 03:48:13 +01:00
|
|
|
|
test_must_be_empty "$actual"
|
2013-06-17 20:31:51 +02:00
|
|
|
|
'
|
|
|
|
|
|
completion: cache the path to the repository
After the previous changes in this series there are only a handful of
$(__gitdir) command substitutions left in the completion script, but
there is still a bit of room for improvements:
1. The command substitution involves the forking of a subshell,
which has considerable overhead on some platforms.
2. There are a few cases, where this command substitution is
executed more than once during a single completion, which means
multiple subshells and possibly multiple 'git rev-parse'
executions. __gitdir() is invoked twice while completing refs
for e.g. 'git log', 'git rebase', 'gitk', or while completing
remote refs for 'git fetch' or 'git push'.
Both of these points can be addressed by using the
__git_find_repo_path() helper function introduced in the previous
commit:
1. __git_find_repo_path() stores the path to the repository in a
variable instead of printing it, so the command substitution
around the function can be avoided. Or rather: the command
substitution should be avoided to make the new value of the
variable set inside the function visible to the callers.
(Yes, there is now a command substitution inside
__git_find_repo_path() around each 'git rev-parse', but that's
executed only if necessary, and only once per completion, see
point 2. below.)
2. $__git_repo_path, the variable holding the path to the
repository, is declared local in the toplevel completion
functions __git_main() and __gitk_main(). Thus, once set, the
path is visible in all completion functions, including all
subsequent calls to __git_find_repo_path(), meaning that they
wouldn't have to re-discover the path to the repository.
So call __git_find_repo_path() and use $__git_repo_path instead of the
$(__gitdir) command substitution to access paths in the .git
directory. Turn tests checking __gitdir()'s repository discovery into
tests of __git_find_repo_path() such that only the tested function
changes but the expected results don't, ensuring that repo discovery
keeps working as it did before.
As __gitdir() is not used anymore in the completion script, mark it as
deprecated and direct users' attention to __git_find_repo_path() and
$__git_repo_path. Yet keep four __gitdir() tests to ensure that it
handles success and failure of __git_find_repo_path() and that it
still handles its optional remote argument, because users' custom
completion scriptlets might depend on it.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:29 +01:00
|
|
|
|
test_expect_success '__gitdir - repo as argument' '
|
|
|
|
|
echo "otherrepo/.git" >expected &&
|
|
|
|
|
(
|
|
|
|
|
__gitdir "otherrepo" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__gitdir - remote as argument' '
|
|
|
|
|
echo "remote" >expected &&
|
|
|
|
|
(
|
|
|
|
|
__gitdir "remote" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: improve handling quoted paths on the command line
Our git-aware path completion doesn't work when it has to complete a
word already containing quoted and/or backslash-escaped characters on
the command line. The root cause of the issue is that completion
functions see all words on the command line verbatim, i.e. including
all backslash, single and double quote characters that the shell would
eventually remove when executing the finished command. These
quoting/escaping characters cause different issues depending on which
path component of the word to be completed contains them:
- The quoting/escaping is in the prefix path component(s).
Let's suppose we have a directory called 'New Dir', containing two
untracked files 'file.c' and 'file.o', and we have a gitignore
rule ignoring object files. In this case all of these:
git add New\ Dir/<TAB>
git add "New Dir/<TAB>
git add 'New Dir/<TAB>
should uniquely complete 'file.c' right away, but Bash offers both
'file.c' and 'file.o' instead. The reason for this behavior is
that our completion script uses the prefix directory name like
'git -C "New\ Dir/" ls-files ...", i.e. with the backslash inside
double quotes. Git then tries to enter a directory called
'New\ Dir', which (most likely) fails because such a directory
doesn't exists. As a result our completion script doesn't list
any files, leaves the COMPREPLY array empty, which in turn causes
Bash to fall back to its simple filename completion and lists all
files in that directory, i.e. both 'file.c' and 'file.o'.
- The quoting/escaping is in the path component to be completed.
Let's suppose we have two untracked files 'New File.c' and
'New File.o', and we have a gitignore rule ignoring object files.
In this case all of these:
git add New\ Fi<TAB>
git add "New Fi<TAB>
git add 'New Fi<TAB>
should uniquely complete 'New File.c' right away, but Bash offers
both 'New File.c' and 'New File.o' instead. The reason for this
behavior is that our completion script uses this 'New\ Fi' or
'"New Fi' etc. word to filter matching paths, and of course none
of the potential filenames will match because of the included
backslash or double quote. The end result is the same as above:
the completion script doesn't list any files, Bash falls back to
its filename completion, which then lists the matching object file
as well.
Add the new helper function __git_dequote() [1], which removes (most
of[2]) the quoting and escaping from the word it gets as argument. To
minimize the overhead of calling this function, store its result in
the variable $dequoted_word, supposed to be declared local in the
caller; simply printing the result would require a command
substitution imposing the overhead of fork()ing a subshell. Use this
function in __git_complete_index_file() to dequote the current word,
i.e. the path, to be completed, to avoid the above described
quoting-related issues, thereby fixing two of the failing quoted path
completion tests.
[1] The bash-completion project already has a dequote() function,
which I hoped I could borrow to deal with this, but unfortunately
it doesn't work quite well for this purpose (perhaps that's why
even the bash-completion project only rarely uses it). The main
issue is that their dequote() is implemented as:
eval printf %s "$1" 2> /dev/null
where $1 would contain the word to be completed. While it's a
short and sweet one-liner, the use of 'eval' requires that $1 is a
syntactically valid string, which is not the case when quoting the
path like 'git add "New Dir/<TAB>'. This causes 'eval' to fail,
because it can't find the matching closing double quote, and the
function returns nothing. The result is totally broken behavior,
as if the current word were empty, and the completion script would
then list all files from the current directory. This is why one
of the quoted path completion tests specifically checks the
completion of a path with an opening but without a corresponding
closing double quote character. Furthermore, the 'eval' performs
all kinds of expansions, which may or may not be desired; I think
it's the latter. Finally, using this function would require a
command substitution.
[2] Bash understands the $'string' quoting as well, which "expands to
'string', with backslash-escaped characters replaced as specified
by the ANSI C standard" (quoted from Bash manpage). Since shell
metacharacters, field separators, globbing, etc. can all be easily
entered using standard shell escaping or quoting, this type of
quoting comes in handly when dealing with control characters that
are otherwise difficult both to "type" and to see on the command
line. Because of this difficulty I would assume that people do
avoid pathnames with such control characters anyway, so I didn't
bother implementing it. This function is already way too long as
it is.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-17 00:41:09 +02:00
|
|
|
|
|
|
|
|
|
test_expect_success '__git_dequote - plain unquoted word' '
|
|
|
|
|
__git_dequote unquoted-word &&
|
|
|
|
|
verbose test unquoted-word = "$dequoted_word"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
# input: b\a\c\k\'\\\"s\l\a\s\h\es
|
|
|
|
|
# expected: back'\"slashes
|
|
|
|
|
test_expect_success '__git_dequote - backslash escaped' '
|
|
|
|
|
__git_dequote "b\a\c\k\\'\''\\\\\\\"s\l\a\s\h\es" &&
|
|
|
|
|
verbose test "back'\''\\\"slashes" = "$dequoted_word"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
# input: sin'gle\' '"quo'ted
|
|
|
|
|
# expected: single\ "quoted
|
|
|
|
|
test_expect_success '__git_dequote - single quoted' '
|
|
|
|
|
__git_dequote "'"sin'gle\\\\' '\\\"quo'ted"'" &&
|
|
|
|
|
verbose test '\''single\ "quoted'\'' = "$dequoted_word"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
# input: dou"ble\\" "\"\quot"ed
|
|
|
|
|
# expected: double\ "\quoted
|
|
|
|
|
test_expect_success '__git_dequote - double quoted' '
|
|
|
|
|
__git_dequote '\''dou"ble\\" "\"\quot"ed'\'' &&
|
|
|
|
|
verbose test '\''double\ "\quoted'\'' = "$dequoted_word"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
# input: 'open single quote
|
|
|
|
|
test_expect_success '__git_dequote - open single quote' '
|
|
|
|
|
__git_dequote "'\''open single quote" &&
|
|
|
|
|
verbose test "open single quote" = "$dequoted_word"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
# input: "open double quote
|
|
|
|
|
test_expect_success '__git_dequote - open double quote' '
|
|
|
|
|
__git_dequote "\"open double quote" &&
|
|
|
|
|
verbose test "open double quote" = "$dequoted_word"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
|
completion: fill COMPREPLY directly when completing refs
__gitcomp_nl() iterates over all the possible completion words it gets
as argument
- filtering matching words,
- appending a trailing space to each matching word (in all but two
cases),
- prepending a prefix to each matching word (when completing words
after e.g. '--option=<TAB>' or 'master..<TAB>'), and
- adding each matching word to the COMPREPLY array.
This takes a while when a lot of refs are passed to __gitcomp_nl().
The previous changes in this series ensure that __git_refs() lists
only refs matching the current word to be completed, making a second
filtering in __gitcomp_nl() redundant.
Adding the necessary prefix and suffix could be done in __git_refs()
as well:
- When refs come from 'git for-each-ref', then that prefix and
suffix could be added much more efficiently using a 'git
for-each-ref' format containing said prefix and suffix. Care
should be taken, though, because that prefix might contain
'for-each-ref' format specifiers as part of the left hand side of
a '..' range or '...' symmetric difference notation or
fetch/push/etc. refspec, e.g. 'git log "evil-%(refname)..br<TAB>'.
Doubling every '%' in the prefix will prevent 'git for-each-ref'
from interpolating any of those contained specifiers.
- When refs come from 'git ls-remote', then that prefix and suffix
can be added in the shell loop that has to process 'git
ls-remote's output anyway.
- Finally, the prefix and suffix can be added to that handful of
potentially matching symbolic and pseudo refs right away in the
shell loop listing them.
And then all what is still left to do is to assign a bunch of
newline-separated words to a shell array, which can be done without a
shell loop iterating over each word, basically making all of
__gitcomp_nl() unnecessary for refs completion.
Add the helper function __gitcomp_direct() to fill the COMPREPLY array
with prefiltered and preprocessed words without any additional
processing, without a shell loop, with just one single compound
assignment. Modify __git_refs() to accept prefix and suffix
parameters and add them to each and every listed ref as described
above. Modify __git_complete_refs() to pass the prefix and suffix
parameters to __git_refs() and to feed __git_refs()'s output to
__gitcomp_direct() instead of __gitcomp_nl().
This speeds up refs completion when there are a lot of refs matching
the current word to be completed. Listing all branches for completion
in a repo with 100k local branches, all packed, best of five:
On Linux, near the beginning of this series, for reference:
$ time __git_complete_refs
real 0m2.028s
user 0m1.692s
sys 0m0.344s
Before this patch:
real 0m1.135s
user 0m1.112s
sys 0m0.024s
After:
real 0m0.367s
user 0m0.352s
sys 0m0.020s
On Windows, near the beginning:
real 0m13.078s
user 0m1.609s
sys 0m0.060s
Before this patch:
real 0m2.093s
user 0m1.641s
sys 0m0.060s
After:
real 0m0.683s
user 0m0.203s
sys 0m0.076s
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-23 16:29:22 +01:00
|
|
|
|
test_expect_success '__gitcomp_direct - puts everything into COMPREPLY as-is' '
|
|
|
|
|
sed -e "s/Z$//g" >expected <<-EOF &&
|
|
|
|
|
with-trailing-space Z
|
|
|
|
|
without-trailing-spaceZ
|
|
|
|
|
--option Z
|
|
|
|
|
--option=Z
|
|
|
|
|
$invalid_variable_name Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=should_be_ignored &&
|
|
|
|
|
__gitcomp_direct "$(cat expected)" &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
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
|
|
|
|
|
'
|
|
|
|
|
|
2018-06-06 11:41:39 +02:00
|
|
|
|
test_expect_success '__gitcomp - ignore optional negative options' '
|
|
|
|
|
test_gitcomp "--" "--abc --def --no-one -- --no-two" <<-\EOF
|
|
|
|
|
--abc Z
|
|
|
|
|
--def Z
|
|
|
|
|
--no-one Z
|
|
|
|
|
--no-... Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp - ignore/narrow optional negative options' '
|
|
|
|
|
test_gitcomp "--a" "--abc --abcdef --no-one -- --no-two" <<-\EOF
|
|
|
|
|
--abc Z
|
|
|
|
|
--abcdef Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp - ignore/narrow optional negative options' '
|
|
|
|
|
test_gitcomp "--n" "--abc --def --no-one -- --no-two" <<-\EOF
|
|
|
|
|
--no-one Z
|
|
|
|
|
--no-... Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp - expand all negative options' '
|
|
|
|
|
test_gitcomp "--no-" "--abc --def --no-one -- --no-two" <<-\EOF
|
|
|
|
|
--no-one Z
|
|
|
|
|
--no-two Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp - expand/narrow all negative options' '
|
|
|
|
|
test_gitcomp "--no-o" "--abc --def --no-one -- --no-two" <<-\EOF
|
|
|
|
|
--no-one Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
2013-04-10 08:57:55 +02:00
|
|
|
|
test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '
|
2013-04-10 08:57:54 +02:00
|
|
|
|
__gitcomp "$invalid_variable_name"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
read -r -d "" refs <<-\EOF
|
|
|
|
|
maint
|
|
|
|
|
master
|
|
|
|
|
next
|
|
|
|
|
pu
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp_nl - trailing space' '
|
|
|
|
|
test_gitcomp_nl "m" "$refs" <<-EOF
|
|
|
|
|
maint Z
|
|
|
|
|
master Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp_nl - prefix' '
|
|
|
|
|
test_gitcomp_nl "--fixup=m" "$refs" "--fixup=" "m" <<-EOF
|
|
|
|
|
--fixup=maint Z
|
|
|
|
|
--fixup=master Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp_nl - suffix' '
|
|
|
|
|
test_gitcomp_nl "branch.ma" "$refs" "branch." "ma" "." <<-\EOF
|
|
|
|
|
branch.maint.Z
|
|
|
|
|
branch.master.Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__gitcomp_nl - no suffix' '
|
|
|
|
|
test_gitcomp_nl "ma" "$refs" "" "ma" "" <<-\EOF
|
|
|
|
|
maintZ
|
|
|
|
|
masterZ
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
2013-04-10 08:57:55 +02:00
|
|
|
|
test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '
|
2013-04-10 08:57:54 +02:00
|
|
|
|
__gitcomp_nl "$invalid_variable_name"
|
|
|
|
|
'
|
|
|
|
|
|
2015-03-04 15:10:28 +01:00
|
|
|
|
test_expect_success '__git_remotes - list remotes from $GIT_DIR/remotes and from config file' '
|
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
|
remote_from_file_1
|
|
|
|
|
remote_from_file_2
|
|
|
|
|
remote_in_config_1
|
|
|
|
|
remote_in_config_2
|
|
|
|
|
EOF
|
|
|
|
|
test_when_finished "rm -rf .git/remotes" &&
|
|
|
|
|
mkdir -p .git/remotes &&
|
|
|
|
|
>.git/remotes/remote_from_file_1 &&
|
|
|
|
|
>.git/remotes/remote_from_file_2 &&
|
|
|
|
|
test_when_finished "git remote remove remote_in_config_1" &&
|
|
|
|
|
git remote add remote_in_config_1 git://remote_1 &&
|
|
|
|
|
test_when_finished "git remote remove remote_in_config_2" &&
|
|
|
|
|
git remote add remote_in_config_2 git://remote_2 &&
|
2017-02-03 03:48:28 +01:00
|
|
|
|
(
|
|
|
|
|
__git_remotes >actual
|
|
|
|
|
) &&
|
2015-03-04 15:10:28 +01:00
|
|
|
|
test_cmp expect actual
|
|
|
|
|
'
|
|
|
|
|
|
2017-02-03 03:48:18 +01:00
|
|
|
|
test_expect_success '__git_is_configured_remote' '
|
|
|
|
|
test_when_finished "git remote remove remote_1" &&
|
|
|
|
|
git remote add remote_1 git://remote_1 &&
|
|
|
|
|
test_when_finished "git remote remove remote_2" &&
|
|
|
|
|
git remote add remote_2 git://remote_2 &&
|
2017-02-03 03:48:28 +01:00
|
|
|
|
(
|
|
|
|
|
verbose __git_is_configured_remote remote_2 &&
|
|
|
|
|
test_must_fail __git_is_configured_remote non-existent
|
|
|
|
|
)
|
2017-02-03 03:48:18 +01:00
|
|
|
|
'
|
|
|
|
|
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
test_expect_success 'setup for ref completion' '
|
|
|
|
|
git commit --allow-empty -m initial &&
|
|
|
|
|
git branch matching-branch &&
|
|
|
|
|
git tag matching-tag &&
|
|
|
|
|
(
|
|
|
|
|
cd otherrepo &&
|
|
|
|
|
git commit --allow-empty -m initial &&
|
|
|
|
|
git branch -m master master-in-other &&
|
|
|
|
|
git branch branch-in-other &&
|
|
|
|
|
git tag tag-in-other
|
|
|
|
|
) &&
|
|
|
|
|
git remote add other "$ROOT/otherrepo/.git" &&
|
|
|
|
|
git fetch --no-tags other &&
|
|
|
|
|
rm -f .git/FETCH_HEAD &&
|
|
|
|
|
git init thirdrepo
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - simple' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
HEAD
|
|
|
|
|
master
|
|
|
|
|
matching-branch
|
|
|
|
|
other/branch-in-other
|
|
|
|
|
other/master-in-other
|
|
|
|
|
matching-tag
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_refs >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - full refs' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
refs/heads/master
|
|
|
|
|
refs/heads/matching-branch
|
completion: let 'for-each-ref' and 'ls-remote' filter matching refs
When completing refs, several __git_refs() code paths list all the
refs from the refs/{heads,tags,remotes}/ hierarchy and then
__gitcomp_nl() iterates over those refs in a shell loop to filter out
refs not matching the current ref to be completed. This comes with a
considerable performance penalty when a repository contains a lot of
refs but the current ref can be uniquely completed or when only a
handful of refs match the current ref.
Reduce the number of iterations in __gitcomp_nl() from the number of
refs to the number of matching refs by specifying appropriate globbing
patterns to 'git for-each-ref' and 'git ls-remote' to list only those
refs that match the current ref to be completed. However, do so only
when the ref to match is explicitly given as parameter, because the
current word on the command line might contain a prefix like
'--option=' or 'branch..'. The __git_complete_refs() and
__git_complete_fetch_refspecs() helpers introduced previously in this
patch series already call __git_refs() specifying this current ref
parameter, so all their callsites, i.e. all places in the completion
script doing refs completion, can benefit from this optimization.
Furthermore, list only those symbolic and pseudo refs that match the
current ref to be completed. Though it doesn't matter at all in
itself performance-wise, it will allow us further significant
optimizations later in this series.
This speeds up refs completion considerably when there are a lot of
non-matching refs to be filtered out. Uniquely completing a branch in
a repository with 100k local branches, all packed, best of five:
On Linux, before:
$ time __git_complete_refs --cur=maste
real 0m0.831s
user 0m0.808s
sys 0m0.028s
After:
real 0m0.119s
user 0m0.104s
sys 0m0.008s
On Windows, before:
real 0m1.480s
user 0m1.031s
sys 0m0.060s
After:
real 0m0.377s
user 0m0.015s
sys 0m0.030s
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-23 16:29:18 +01:00
|
|
|
|
refs/remotes/other/branch-in-other
|
|
|
|
|
refs/remotes/other/master-in-other
|
|
|
|
|
refs/tags/matching-tag
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=refs/heads/ &&
|
|
|
|
|
__git_refs >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - repo given on the command line' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
HEAD
|
|
|
|
|
branch-in-other
|
|
|
|
|
master-in-other
|
|
|
|
|
tag-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
__git_dir="$ROOT/otherrepo/.git" &&
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_refs >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - remote on local file system' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
HEAD
|
|
|
|
|
branch-in-other
|
|
|
|
|
master-in-other
|
|
|
|
|
tag-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_refs otherrepo >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - remote on local file system - full refs' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
refs/heads/branch-in-other
|
|
|
|
|
refs/heads/master-in-other
|
|
|
|
|
refs/tags/tag-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=refs/ &&
|
|
|
|
|
__git_refs otherrepo >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - configured remote' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
HEAD
|
|
|
|
|
branch-in-other
|
|
|
|
|
master-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_refs other >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - configured remote - full refs' '
|
|
|
|
|
cat >expected <<-EOF &&
|
completion: let 'for-each-ref' and 'ls-remote' filter matching refs
When completing refs, several __git_refs() code paths list all the
refs from the refs/{heads,tags,remotes}/ hierarchy and then
__gitcomp_nl() iterates over those refs in a shell loop to filter out
refs not matching the current ref to be completed. This comes with a
considerable performance penalty when a repository contains a lot of
refs but the current ref can be uniquely completed or when only a
handful of refs match the current ref.
Reduce the number of iterations in __gitcomp_nl() from the number of
refs to the number of matching refs by specifying appropriate globbing
patterns to 'git for-each-ref' and 'git ls-remote' to list only those
refs that match the current ref to be completed. However, do so only
when the ref to match is explicitly given as parameter, because the
current word on the command line might contain a prefix like
'--option=' or 'branch..'. The __git_complete_refs() and
__git_complete_fetch_refspecs() helpers introduced previously in this
patch series already call __git_refs() specifying this current ref
parameter, so all their callsites, i.e. all places in the completion
script doing refs completion, can benefit from this optimization.
Furthermore, list only those symbolic and pseudo refs that match the
current ref to be completed. Though it doesn't matter at all in
itself performance-wise, it will allow us further significant
optimizations later in this series.
This speeds up refs completion considerably when there are a lot of
non-matching refs to be filtered out. Uniquely completing a branch in
a repository with 100k local branches, all packed, best of five:
On Linux, before:
$ time __git_complete_refs --cur=maste
real 0m0.831s
user 0m0.808s
sys 0m0.028s
After:
real 0m0.119s
user 0m0.104s
sys 0m0.008s
On Windows, before:
real 0m1.480s
user 0m1.031s
sys 0m0.060s
After:
real 0m0.377s
user 0m0.015s
sys 0m0.030s
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-23 16:29:18 +01:00
|
|
|
|
HEAD
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
refs/heads/branch-in-other
|
|
|
|
|
refs/heads/master-in-other
|
|
|
|
|
refs/tags/tag-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=refs/ &&
|
|
|
|
|
__git_refs other >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
2017-02-03 03:48:17 +01:00
|
|
|
|
test_expect_success '__git_refs - configured remote - repo given on the command line' '
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
HEAD
|
|
|
|
|
branch-in-other
|
|
|
|
|
master-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cd thirdrepo &&
|
|
|
|
|
__git_dir="$ROOT/.git" &&
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_refs other >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
2017-02-03 03:48:17 +01:00
|
|
|
|
test_expect_success '__git_refs - configured remote - full refs - repo given on the command line' '
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
cat >expected <<-EOF &&
|
completion: let 'for-each-ref' and 'ls-remote' filter matching refs
When completing refs, several __git_refs() code paths list all the
refs from the refs/{heads,tags,remotes}/ hierarchy and then
__gitcomp_nl() iterates over those refs in a shell loop to filter out
refs not matching the current ref to be completed. This comes with a
considerable performance penalty when a repository contains a lot of
refs but the current ref can be uniquely completed or when only a
handful of refs match the current ref.
Reduce the number of iterations in __gitcomp_nl() from the number of
refs to the number of matching refs by specifying appropriate globbing
patterns to 'git for-each-ref' and 'git ls-remote' to list only those
refs that match the current ref to be completed. However, do so only
when the ref to match is explicitly given as parameter, because the
current word on the command line might contain a prefix like
'--option=' or 'branch..'. The __git_complete_refs() and
__git_complete_fetch_refspecs() helpers introduced previously in this
patch series already call __git_refs() specifying this current ref
parameter, so all their callsites, i.e. all places in the completion
script doing refs completion, can benefit from this optimization.
Furthermore, list only those symbolic and pseudo refs that match the
current ref to be completed. Though it doesn't matter at all in
itself performance-wise, it will allow us further significant
optimizations later in this series.
This speeds up refs completion considerably when there are a lot of
non-matching refs to be filtered out. Uniquely completing a branch in
a repository with 100k local branches, all packed, best of five:
On Linux, before:
$ time __git_complete_refs --cur=maste
real 0m0.831s
user 0m0.808s
sys 0m0.028s
After:
real 0m0.119s
user 0m0.104s
sys 0m0.008s
On Windows, before:
real 0m1.480s
user 0m1.031s
sys 0m0.060s
After:
real 0m0.377s
user 0m0.015s
sys 0m0.030s
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-23 16:29:18 +01:00
|
|
|
|
HEAD
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
refs/heads/branch-in-other
|
|
|
|
|
refs/heads/master-in-other
|
|
|
|
|
refs/tags/tag-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cd thirdrepo &&
|
|
|
|
|
__git_dir="$ROOT/.git" &&
|
|
|
|
|
cur=refs/ &&
|
|
|
|
|
__git_refs other >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
2017-02-03 03:48:18 +01:00
|
|
|
|
test_expect_success '__git_refs - configured remote - remote name matches a directory' '
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
HEAD
|
|
|
|
|
branch-in-other
|
|
|
|
|
master-in-other
|
|
|
|
|
EOF
|
|
|
|
|
mkdir other &&
|
|
|
|
|
test_when_finished "rm -rf other" &&
|
|
|
|
|
(
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_refs other >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: list short refs from a remote given as a URL
e832f5c09680 (completion: avoid ls-remote in certain scenarios,
2013-05-28) turned a 'git ls-remote <remote>' query into a 'git
for-each-ref refs/remotes/<remote>/' to improve responsiveness of
remote refs completion by avoiding potential network communication.
However, it inadvertently made impossible to complete short refs from
a remote given as a URL, e.g. 'git fetch git://server.com/repo.git
<TAB>', because there is, of course, no such thing as
'refs/remotes/git://server.com/repo.git'.
Since the previous commit we tell apart configured remotes, i.e. those
that can have a hierarchy under 'refs/remotes/', from others that
don't, including remotes given as URL, so we know when we can't use
the faster 'git for-each-ref'-based approach.
Resurrect the old, pre-e832f5c09680 'git ls-remote'-based code for the
latter case to support listing short refs from remotes given as a URL.
The code is slightly updated from the original to
- take into account the path to the repository given on the command
line (if any), and
- omit 'ORIG_HEAD' from the query, as 'git ls-remote' will never
list it anyway.
When the remote given to __git_refs() doesn't exist, then it will be
handled by this resurrected 'git ls-remote' query. This code path
doesn't list 'HEAD' unconditionally, which has the nice side effect of
fixing two more expected test failures.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:20 +01:00
|
|
|
|
test_expect_success '__git_refs - URL remote' '
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
HEAD
|
|
|
|
|
branch-in-other
|
|
|
|
|
master-in-other
|
|
|
|
|
tag-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_refs "file://$ROOT/otherrepo/.git" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - URL remote - full refs' '
|
|
|
|
|
cat >expected <<-EOF &&
|
completion: let 'for-each-ref' and 'ls-remote' filter matching refs
When completing refs, several __git_refs() code paths list all the
refs from the refs/{heads,tags,remotes}/ hierarchy and then
__gitcomp_nl() iterates over those refs in a shell loop to filter out
refs not matching the current ref to be completed. This comes with a
considerable performance penalty when a repository contains a lot of
refs but the current ref can be uniquely completed or when only a
handful of refs match the current ref.
Reduce the number of iterations in __gitcomp_nl() from the number of
refs to the number of matching refs by specifying appropriate globbing
patterns to 'git for-each-ref' and 'git ls-remote' to list only those
refs that match the current ref to be completed. However, do so only
when the ref to match is explicitly given as parameter, because the
current word on the command line might contain a prefix like
'--option=' or 'branch..'. The __git_complete_refs() and
__git_complete_fetch_refspecs() helpers introduced previously in this
patch series already call __git_refs() specifying this current ref
parameter, so all their callsites, i.e. all places in the completion
script doing refs completion, can benefit from this optimization.
Furthermore, list only those symbolic and pseudo refs that match the
current ref to be completed. Though it doesn't matter at all in
itself performance-wise, it will allow us further significant
optimizations later in this series.
This speeds up refs completion considerably when there are a lot of
non-matching refs to be filtered out. Uniquely completing a branch in
a repository with 100k local branches, all packed, best of five:
On Linux, before:
$ time __git_complete_refs --cur=maste
real 0m0.831s
user 0m0.808s
sys 0m0.028s
After:
real 0m0.119s
user 0m0.104s
sys 0m0.008s
On Windows, before:
real 0m1.480s
user 0m1.031s
sys 0m0.060s
After:
real 0m0.377s
user 0m0.015s
sys 0m0.030s
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-23 16:29:18 +01:00
|
|
|
|
HEAD
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
refs/heads/branch-in-other
|
|
|
|
|
refs/heads/master-in-other
|
|
|
|
|
refs/tags/tag-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=refs/ &&
|
|
|
|
|
__git_refs "file://$ROOT/otherrepo/.git" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: list short refs from a remote given as a URL
e832f5c09680 (completion: avoid ls-remote in certain scenarios,
2013-05-28) turned a 'git ls-remote <remote>' query into a 'git
for-each-ref refs/remotes/<remote>/' to improve responsiveness of
remote refs completion by avoiding potential network communication.
However, it inadvertently made impossible to complete short refs from
a remote given as a URL, e.g. 'git fetch git://server.com/repo.git
<TAB>', because there is, of course, no such thing as
'refs/remotes/git://server.com/repo.git'.
Since the previous commit we tell apart configured remotes, i.e. those
that can have a hierarchy under 'refs/remotes/', from others that
don't, including remotes given as URL, so we know when we can't use
the faster 'git for-each-ref'-based approach.
Resurrect the old, pre-e832f5c09680 'git ls-remote'-based code for the
latter case to support listing short refs from remotes given as a URL.
The code is slightly updated from the original to
- take into account the path to the repository given on the command
line (if any), and
- omit 'ORIG_HEAD' from the query, as 'git ls-remote' will never
list it anyway.
When the remote given to __git_refs() doesn't exist, then it will be
handled by this resurrected 'git ls-remote' query. This code path
doesn't list 'HEAD' unconditionally, which has the nice side effect of
fixing two more expected test failures.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:20 +01:00
|
|
|
|
test_expect_success '__git_refs - non-existing remote' '
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
(
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_refs non-existing >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_must_be_empty "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - non-existing remote - full refs' '
|
|
|
|
|
(
|
|
|
|
|
cur=refs/ &&
|
|
|
|
|
__git_refs non-existing >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_must_be_empty "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: list short refs from a remote given as a URL
e832f5c09680 (completion: avoid ls-remote in certain scenarios,
2013-05-28) turned a 'git ls-remote <remote>' query into a 'git
for-each-ref refs/remotes/<remote>/' to improve responsiveness of
remote refs completion by avoiding potential network communication.
However, it inadvertently made impossible to complete short refs from
a remote given as a URL, e.g. 'git fetch git://server.com/repo.git
<TAB>', because there is, of course, no such thing as
'refs/remotes/git://server.com/repo.git'.
Since the previous commit we tell apart configured remotes, i.e. those
that can have a hierarchy under 'refs/remotes/', from others that
don't, including remotes given as URL, so we know when we can't use
the faster 'git for-each-ref'-based approach.
Resurrect the old, pre-e832f5c09680 'git ls-remote'-based code for the
latter case to support listing short refs from remotes given as a URL.
The code is slightly updated from the original to
- take into account the path to the repository given on the command
line (if any), and
- omit 'ORIG_HEAD' from the query, as 'git ls-remote' will never
list it anyway.
When the remote given to __git_refs() doesn't exist, then it will be
handled by this resurrected 'git ls-remote' query. This code path
doesn't list 'HEAD' unconditionally, which has the nice side effect of
fixing two more expected test failures.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:20 +01:00
|
|
|
|
test_expect_success '__git_refs - non-existing URL remote' '
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
(
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_refs "file://$ROOT/non-existing" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_must_be_empty "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - non-existing URL remote - full refs' '
|
|
|
|
|
(
|
|
|
|
|
cur=refs/ &&
|
|
|
|
|
__git_refs "file://$ROOT/non-existing" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_must_be_empty "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
2017-02-03 03:48:19 +01:00
|
|
|
|
test_expect_success '__git_refs - not in a git repository' '
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
(
|
|
|
|
|
GIT_CEILING_DIRECTORIES="$ROOT" &&
|
|
|
|
|
export GIT_CEILING_DIRECTORIES &&
|
|
|
|
|
cd subdir &&
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_refs >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_must_be_empty "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - unique remote branches for git checkout DWIMery' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
HEAD
|
|
|
|
|
master
|
|
|
|
|
matching-branch
|
|
|
|
|
other/ambiguous
|
|
|
|
|
other/branch-in-other
|
|
|
|
|
other/master-in-other
|
|
|
|
|
remote/ambiguous
|
|
|
|
|
remote/branch-in-remote
|
|
|
|
|
matching-tag
|
|
|
|
|
branch-in-other
|
|
|
|
|
branch-in-remote
|
|
|
|
|
master-in-other
|
|
|
|
|
EOF
|
|
|
|
|
for remote_ref in refs/remotes/other/ambiguous \
|
|
|
|
|
refs/remotes/remote/ambiguous \
|
|
|
|
|
refs/remotes/remote/branch-in-remote
|
|
|
|
|
do
|
|
|
|
|
git update-ref $remote_ref master &&
|
|
|
|
|
test_when_finished "git update-ref -d $remote_ref"
|
|
|
|
|
done &&
|
|
|
|
|
(
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_refs "" 1 >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
2017-03-23 16:29:13 +01:00
|
|
|
|
test_expect_success '__git_refs - after --opt=' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
HEAD
|
|
|
|
|
master
|
|
|
|
|
matching-branch
|
|
|
|
|
other/branch-in-other
|
|
|
|
|
other/master-in-other
|
|
|
|
|
matching-tag
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur="--opt=" &&
|
|
|
|
|
__git_refs "" "" "" "" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - after --opt= - full refs' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
refs/heads/master
|
|
|
|
|
refs/heads/matching-branch
|
|
|
|
|
refs/remotes/other/branch-in-other
|
|
|
|
|
refs/remotes/other/master-in-other
|
|
|
|
|
refs/tags/matching-tag
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur="--opt=refs/" &&
|
|
|
|
|
__git_refs "" "" "" refs/ >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
2017-03-23 16:29:15 +01:00
|
|
|
|
test_expect_success '__git refs - exluding refs' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
^HEAD
|
|
|
|
|
^master
|
|
|
|
|
^matching-branch
|
|
|
|
|
^other/branch-in-other
|
|
|
|
|
^other/master-in-other
|
|
|
|
|
^matching-tag
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=^ &&
|
|
|
|
|
__git_refs >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git refs - exluding full refs' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
^refs/heads/master
|
|
|
|
|
^refs/heads/matching-branch
|
|
|
|
|
^refs/remotes/other/branch-in-other
|
|
|
|
|
^refs/remotes/other/master-in-other
|
|
|
|
|
^refs/tags/matching-tag
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=^refs/ &&
|
|
|
|
|
__git_refs >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: let 'for-each-ref' and 'ls-remote' filter matching refs
When completing refs, several __git_refs() code paths list all the
refs from the refs/{heads,tags,remotes}/ hierarchy and then
__gitcomp_nl() iterates over those refs in a shell loop to filter out
refs not matching the current ref to be completed. This comes with a
considerable performance penalty when a repository contains a lot of
refs but the current ref can be uniquely completed or when only a
handful of refs match the current ref.
Reduce the number of iterations in __gitcomp_nl() from the number of
refs to the number of matching refs by specifying appropriate globbing
patterns to 'git for-each-ref' and 'git ls-remote' to list only those
refs that match the current ref to be completed. However, do so only
when the ref to match is explicitly given as parameter, because the
current word on the command line might contain a prefix like
'--option=' or 'branch..'. The __git_complete_refs() and
__git_complete_fetch_refspecs() helpers introduced previously in this
patch series already call __git_refs() specifying this current ref
parameter, so all their callsites, i.e. all places in the completion
script doing refs completion, can benefit from this optimization.
Furthermore, list only those symbolic and pseudo refs that match the
current ref to be completed. Though it doesn't matter at all in
itself performance-wise, it will allow us further significant
optimizations later in this series.
This speeds up refs completion considerably when there are a lot of
non-matching refs to be filtered out. Uniquely completing a branch in
a repository with 100k local branches, all packed, best of five:
On Linux, before:
$ time __git_complete_refs --cur=maste
real 0m0.831s
user 0m0.808s
sys 0m0.028s
After:
real 0m0.119s
user 0m0.104s
sys 0m0.008s
On Windows, before:
real 0m1.480s
user 0m1.031s
sys 0m0.060s
After:
real 0m0.377s
user 0m0.015s
sys 0m0.030s
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-23 16:29:18 +01:00
|
|
|
|
test_expect_success 'setup for filtering matching refs' '
|
|
|
|
|
git branch matching/branch &&
|
|
|
|
|
git tag matching/tag &&
|
|
|
|
|
git -C otherrepo branch matching/branch-in-other &&
|
|
|
|
|
git fetch --no-tags other &&
|
|
|
|
|
rm -f .git/FETCH_HEAD
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - dont filter refs unless told so' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
HEAD
|
|
|
|
|
master
|
|
|
|
|
matching-branch
|
|
|
|
|
matching/branch
|
|
|
|
|
other/branch-in-other
|
|
|
|
|
other/master-in-other
|
|
|
|
|
other/matching/branch-in-other
|
|
|
|
|
matching-tag
|
|
|
|
|
matching/tag
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=master &&
|
|
|
|
|
__git_refs >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - only matching refs' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
matching-branch
|
|
|
|
|
matching/branch
|
|
|
|
|
matching-tag
|
|
|
|
|
matching/tag
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=mat &&
|
|
|
|
|
__git_refs "" "" "" "$cur" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - only matching refs - full refs' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
refs/heads/matching-branch
|
|
|
|
|
refs/heads/matching/branch
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=refs/heads/mat &&
|
|
|
|
|
__git_refs "" "" "" "$cur" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - only matching refs - remote on local file system' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
master-in-other
|
|
|
|
|
matching/branch-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=ma &&
|
|
|
|
|
__git_refs otherrepo "" "" "$cur" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - only matching refs - configured remote' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
master-in-other
|
|
|
|
|
matching/branch-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=ma &&
|
|
|
|
|
__git_refs other "" "" "$cur" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - only matching refs - remote - full refs' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
refs/heads/master-in-other
|
|
|
|
|
refs/heads/matching/branch-in-other
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=refs/heads/ma &&
|
|
|
|
|
__git_refs other "" "" "$cur" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_refs - only matching refs - checkout DWIMery' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
matching-branch
|
|
|
|
|
matching/branch
|
|
|
|
|
matching-tag
|
|
|
|
|
matching/tag
|
|
|
|
|
matching/branch-in-other
|
|
|
|
|
EOF
|
|
|
|
|
for remote_ref in refs/remotes/other/ambiguous \
|
|
|
|
|
refs/remotes/remote/ambiguous \
|
|
|
|
|
refs/remotes/remote/branch-in-remote
|
|
|
|
|
do
|
|
|
|
|
git update-ref $remote_ref master &&
|
|
|
|
|
test_when_finished "git update-ref -d $remote_ref"
|
|
|
|
|
done &&
|
|
|
|
|
(
|
|
|
|
|
cur=mat &&
|
|
|
|
|
__git_refs "" 1 "" "$cur" >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success 'teardown after filtering matching refs' '
|
|
|
|
|
git branch -d matching/branch &&
|
|
|
|
|
git tag -d matching/tag &&
|
|
|
|
|
git update-ref -d refs/remotes/other/matching/branch-in-other &&
|
|
|
|
|
git -C otherrepo branch -D matching/branch-in-other
|
|
|
|
|
'
|
|
|
|
|
|
completion: fill COMPREPLY directly when completing refs
__gitcomp_nl() iterates over all the possible completion words it gets
as argument
- filtering matching words,
- appending a trailing space to each matching word (in all but two
cases),
- prepending a prefix to each matching word (when completing words
after e.g. '--option=<TAB>' or 'master..<TAB>'), and
- adding each matching word to the COMPREPLY array.
This takes a while when a lot of refs are passed to __gitcomp_nl().
The previous changes in this series ensure that __git_refs() lists
only refs matching the current word to be completed, making a second
filtering in __gitcomp_nl() redundant.
Adding the necessary prefix and suffix could be done in __git_refs()
as well:
- When refs come from 'git for-each-ref', then that prefix and
suffix could be added much more efficiently using a 'git
for-each-ref' format containing said prefix and suffix. Care
should be taken, though, because that prefix might contain
'for-each-ref' format specifiers as part of the left hand side of
a '..' range or '...' symmetric difference notation or
fetch/push/etc. refspec, e.g. 'git log "evil-%(refname)..br<TAB>'.
Doubling every '%' in the prefix will prevent 'git for-each-ref'
from interpolating any of those contained specifiers.
- When refs come from 'git ls-remote', then that prefix and suffix
can be added in the shell loop that has to process 'git
ls-remote's output anyway.
- Finally, the prefix and suffix can be added to that handful of
potentially matching symbolic and pseudo refs right away in the
shell loop listing them.
And then all what is still left to do is to assign a bunch of
newline-separated words to a shell array, which can be done without a
shell loop iterating over each word, basically making all of
__gitcomp_nl() unnecessary for refs completion.
Add the helper function __gitcomp_direct() to fill the COMPREPLY array
with prefiltered and preprocessed words without any additional
processing, without a shell loop, with just one single compound
assignment. Modify __git_refs() to accept prefix and suffix
parameters and add them to each and every listed ref as described
above. Modify __git_complete_refs() to pass the prefix and suffix
parameters to __git_refs() and to feed __git_refs()'s output to
__gitcomp_direct() instead of __gitcomp_nl().
This speeds up refs completion when there are a lot of refs matching
the current word to be completed. Listing all branches for completion
in a repo with 100k local branches, all packed, best of five:
On Linux, near the beginning of this series, for reference:
$ time __git_complete_refs
real 0m2.028s
user 0m1.692s
sys 0m0.344s
Before this patch:
real 0m1.135s
user 0m1.112s
sys 0m0.024s
After:
real 0m0.367s
user 0m0.352s
sys 0m0.020s
On Windows, near the beginning:
real 0m13.078s
user 0m1.609s
sys 0m0.060s
Before this patch:
real 0m2.093s
user 0m1.641s
sys 0m0.060s
After:
real 0m0.683s
user 0m0.203s
sys 0m0.076s
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-23 16:29:22 +01:00
|
|
|
|
test_expect_success '__git_refs - for-each-ref format specifiers in prefix' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
evil-%%-%42-%(refname)..master
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur="evil-%%-%42-%(refname)..mas" &&
|
|
|
|
|
__git_refs "" "" "evil-%%-%42-%(refname).." mas >"$actual"
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected "$actual"
|
|
|
|
|
'
|
|
|
|
|
|
completion: wrap __git_refs() for better option parsing
__git_refs() currently accepts two optional positional parameters: a
remote and a flag for 'git checkout's tracking DWIMery. To fix a
minor bug, and, more importantly, for faster refs completion, this
series will add three more parameters: a prefix, the current word to
be completed and a suffix, i.e. the options accepted by __gitcomp() &
friends, and will change __git_refs() to list only refs matching that
given current word and to add that given prefix and suffix to the
listed refs.
However, __git_refs() is the helper function that is most likely used
in users' custom completion scriptlets for their own git commands, and
we don't want to break those, so
- we can't change __git_refs()'s default output format, i.e. we
can't by default append a trailing space to every listed ref,
meaning that the suffix parameter containing the default trailing
space would have to be specified on every invocation, and
- we can't change the position of existing positional parameters
either, so there would have to be plenty of set-but-empty
placeholder positional parameters all over the completion script.
Furthermore, with five positional parameters it would be really hard
to remember which position means what.
To keep callsites simple, add the new wrapper function
__git_complete_refs() around __git_refs(), which:
- instead of positional parameters accepts real '--opt=val'-style
options and with minimalistic option parsing translates them to
__git_refs()'s and __gitcomp_nl()'s positional parameters, and
- includes the '__gitcomp_nl "$(__git_refs ...)" ...' command
substitution to make its behavior match its name and the behavior
of other __git_complete_* functions, and to limit future changes
in this series to __git_refs() and this new wrapper function.
Call this wrapper function instead of __git_refs() wherever possible
throughout the completion script, i.e. when __git_refs()'s output is
fed to __gitcomp_nl() right away without further processing, which
means all callsites except a single one in the __git_refs2() helper.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-23 16:29:12 +01:00
|
|
|
|
test_expect_success '__git_complete_refs - simple' '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
HEAD Z
|
|
|
|
|
master Z
|
|
|
|
|
matching-branch Z
|
|
|
|
|
other/branch-in-other Z
|
|
|
|
|
other/master-in-other Z
|
|
|
|
|
matching-tag Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_complete_refs &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_refs - matching' '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
matching-branch Z
|
|
|
|
|
matching-tag Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=mat &&
|
|
|
|
|
__git_complete_refs &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_refs - remote' '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
HEAD Z
|
|
|
|
|
branch-in-other Z
|
|
|
|
|
master-in-other Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=
|
|
|
|
|
__git_complete_refs --remote=other &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_refs - track' '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
HEAD Z
|
|
|
|
|
master Z
|
|
|
|
|
matching-branch Z
|
|
|
|
|
other/branch-in-other Z
|
|
|
|
|
other/master-in-other Z
|
|
|
|
|
matching-tag Z
|
|
|
|
|
branch-in-other Z
|
|
|
|
|
master-in-other Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=
|
|
|
|
|
__git_complete_refs --track &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_refs - current word' '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
matching-branch Z
|
|
|
|
|
matching-tag Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur="--option=mat" &&
|
|
|
|
|
__git_complete_refs --cur="${cur#*=}" &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_refs - prefix' '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
v1.0..matching-branch Z
|
|
|
|
|
v1.0..matching-tag Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=v1.0..mat &&
|
|
|
|
|
__git_complete_refs --pfx=v1.0.. --cur=mat &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_refs - suffix' '
|
|
|
|
|
cat >expected <<-EOF &&
|
|
|
|
|
HEAD.
|
|
|
|
|
master.
|
|
|
|
|
matching-branch.
|
|
|
|
|
other/branch-in-other.
|
|
|
|
|
other/master-in-other.
|
|
|
|
|
matching-tag.
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_complete_refs --sfx=. &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
completion: support completing fully qualified non-fast-forward refspecs
After 'git fetch <remote> <TAB>' our completion script offers refspecs
that will fetch to a local branch with the same name as in the remote
repository, e.g. 'master:master'. This also completes
non-fast-forward refspecs, i.e. after a '+' prefix like
'+master:master', and fully qualified refspecs, e.g.
'refs/heads/master:refs/heads/master'. However, it does not complete
non-fast-forward fully qualified refspecs (or fully qualified refspecs
following any other prefix, e.g. '--option=', though currently no git
command supports such an option, but third party git commands might).
These refspecs are listed by the __git_refs2() function, which is just
a thin wrapper iterating over __git_refs()'s output, turning each
listed ref into a refspec. Now, it's certainly possible to modify
__git_refs2() and its callsite to pass an extra parameter containing
only the ref part of the current word to be completed (to follow suit
of the previous commit) to deal with prefixed fully qualified refspecs
as well. Unfortunately, keeping the current behavior unchanged in the
"no extra parameter" case brings in a bit of subtlety, which makes the
resulting code ugly and compelled me to write a 8-line long comment in
the proof of concept. Not good. However, since the callsite has to
be modified for proper functioning anyway, we might as well leave
__git_refs2() as is and introduce a new helper function without
backwards compatibility concerns.
Add the new function __git_complete_fetch_refspecs() that has all the
necessary parameters to do the right thing in all cases mentioned
above, including non-fast-forward fully qualified refspecs. This new
function can also easier benefit from optimizations coming later in
this patch series.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-03-23 16:29:14 +01:00
|
|
|
|
test_expect_success '__git_complete_fetch_refspecs - simple' '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
HEAD:HEAD Z
|
|
|
|
|
branch-in-other:branch-in-other Z
|
|
|
|
|
master-in-other:master-in-other Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur= &&
|
|
|
|
|
__git_complete_fetch_refspecs other &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_fetch_refspecs - matching' '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
branch-in-other:branch-in-other Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=br &&
|
|
|
|
|
__git_complete_fetch_refspecs other "" br &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_fetch_refspecs - prefix' '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
+HEAD:HEAD Z
|
|
|
|
|
+branch-in-other:branch-in-other Z
|
|
|
|
|
+master-in-other:master-in-other Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur="+" &&
|
|
|
|
|
__git_complete_fetch_refspecs other "+" "" &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_fetch_refspecs - fully qualified' '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
refs/heads/branch-in-other:refs/heads/branch-in-other Z
|
|
|
|
|
refs/heads/master-in-other:refs/heads/master-in-other Z
|
|
|
|
|
refs/tags/tag-in-other:refs/tags/tag-in-other Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=refs/ &&
|
|
|
|
|
__git_complete_fetch_refspecs other "" refs/ &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_fetch_refspecs - fully qualified & prefix' '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
+refs/heads/branch-in-other:refs/heads/branch-in-other Z
|
|
|
|
|
+refs/heads/master-in-other:refs/heads/master-in-other Z
|
|
|
|
|
+refs/tags/tag-in-other:refs/tags/tag-in-other Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
cur=+refs/ &&
|
|
|
|
|
__git_complete_fetch_refspecs other + refs/ &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
test_expect_success 'teardown after ref completion' '
|
|
|
|
|
git branch -d matching-branch &&
|
|
|
|
|
git tag -d matching-tag &&
|
|
|
|
|
git remote remove other
|
|
|
|
|
'
|
|
|
|
|
|
t9902-completion: exercise __git_complete_index_file() directly
The tests added in 2f271cd9cf (t9902-completion: add tests
demonstrating issues with quoted pathnames, 2018-05-08) and in
2ab6eab4fe (completion: improve handling quoted paths in 'git
ls-files's output, 2018-03-28) have a few shortcomings:
- All these tests use the 'test_completion' helper function, thus
they are exercising the whole completion machinery, although they
are only interested in how git-aware path completion, specifically
the __git_complete_index_file() function deals with unusual
characters in pathnames and on the command line.
- These tests can't satisfactorily test the case of pathnames
containing spaces, because 'test_completion' gets the words on the
command line as a single argument and it uses space as word
separator.
- Some of the tests are protected by different FUNNYNAMES_* prereqs
depending on whether they put backslashes and double quotes or
separator characters (FS, GS, RS, US) in pathnames, although a
filesystem not allowing one likely doesn't allow the others
either.
- One of the tests operates on paths containing '|' and '&'
characters without being protected by a FUNNYNAMES prereq, but
some filesystems (notably on Windows) don't allow these characters
in pathnames, either.
Replace these tests with basically equivalent, more focused tests that
call __git_complete_index_file() directly. Since this function only
looks at the current word to be completed, i.e. the $cur variable, we
can easily include pathnames containing spaces in the tests, so use
such pathnames instead of pathnames containing '|' and '&'. Finally,
use only a single FUNNYNAMES prereq for all kinds of special
characters.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-18 16:17:51 +02:00
|
|
|
|
|
|
|
|
|
test_path_completion ()
|
|
|
|
|
{
|
|
|
|
|
test $# = 2 || error "bug in the test script: not 2 parameters to test_path_completion"
|
|
|
|
|
|
|
|
|
|
local cur="$1" expected="$2"
|
|
|
|
|
echo "$expected" >expected &&
|
|
|
|
|
(
|
|
|
|
|
# In the following tests calling this function we only
|
|
|
|
|
# care about how __git_complete_index_file() deals with
|
|
|
|
|
# unusual characters in path names. By requesting only
|
|
|
|
|
# untracked files we dont have to bother adding any
|
|
|
|
|
# paths to the index in those tests.
|
|
|
|
|
__git_complete_index_file --others &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
test_expect_success 'setup for path completion tests' '
|
|
|
|
|
mkdir simple-dir \
|
|
|
|
|
"spaces in dir" \
|
|
|
|
|
árvíztűrő &&
|
|
|
|
|
touch simple-dir/simple-file \
|
|
|
|
|
"spaces in dir/spaces in file" \
|
|
|
|
|
"árvíztűrő/Сайн яваарай" &&
|
|
|
|
|
if test_have_prereq !MINGW &&
|
|
|
|
|
mkdir BS\\dir \
|
|
|
|
|
'$'separators\034in\035dir'' &&
|
|
|
|
|
touch BS\\dir/DQ\"file \
|
|
|
|
|
'$'separators\034in\035dir/sep\036in\037file''
|
|
|
|
|
then
|
|
|
|
|
test_set_prereq FUNNYNAMES
|
|
|
|
|
else
|
|
|
|
|
rm -rf BS\\dir '$'separators\034in\035dir''
|
|
|
|
|
fi
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_index_file - simple' '
|
|
|
|
|
test_path_completion simple simple-dir && # Bash is supposed to
|
|
|
|
|
# add the trailing /.
|
|
|
|
|
test_path_completion simple-dir/simple simple-dir/simple-file
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success \
|
|
|
|
|
'__git_complete_index_file - escaped characters on cmdline' '
|
|
|
|
|
test_path_completion spac "spaces in dir" && # Bash will turn this
|
|
|
|
|
# into "spaces\ in\ dir"
|
|
|
|
|
test_path_completion "spaces\\ i" \
|
|
|
|
|
"spaces in dir" &&
|
|
|
|
|
test_path_completion "spaces\\ in\\ dir/s" \
|
|
|
|
|
"spaces in dir/spaces in file" &&
|
|
|
|
|
test_path_completion "spaces\\ in\\ dir/spaces\\ i" \
|
|
|
|
|
"spaces in dir/spaces in file"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success \
|
|
|
|
|
'__git_complete_index_file - quoted characters on cmdline' '
|
|
|
|
|
# Testing with an opening but without a corresponding closing
|
|
|
|
|
# double quote is important.
|
|
|
|
|
test_path_completion \"spac "spaces in dir" &&
|
|
|
|
|
test_path_completion "\"spaces i" \
|
|
|
|
|
"spaces in dir" &&
|
|
|
|
|
test_path_completion "\"spaces in dir/s" \
|
|
|
|
|
"spaces in dir/spaces in file" &&
|
|
|
|
|
test_path_completion "\"spaces in dir/spaces i" \
|
|
|
|
|
"spaces in dir/spaces in file"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success '__git_complete_index_file - UTF-8 in ls-files output' '
|
|
|
|
|
test_path_completion á árvíztűrő &&
|
|
|
|
|
test_path_completion árvíztűrő/С "árvíztűrő/Сайн яваарай"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success FUNNYNAMES \
|
|
|
|
|
'__git_complete_index_file - C-style escapes in ls-files output' '
|
|
|
|
|
test_path_completion BS \
|
|
|
|
|
BS\\dir &&
|
|
|
|
|
test_path_completion BS\\\\d \
|
|
|
|
|
BS\\dir &&
|
|
|
|
|
test_path_completion BS\\\\dir/DQ \
|
|
|
|
|
BS\\dir/DQ\"file &&
|
|
|
|
|
test_path_completion BS\\\\dir/DQ\\\"f \
|
|
|
|
|
BS\\dir/DQ\"file
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success FUNNYNAMES \
|
|
|
|
|
'__git_complete_index_file - \nnn-escaped characters in ls-files output' '
|
|
|
|
|
test_path_completion sep '$'separators\034in\035dir'' &&
|
|
|
|
|
test_path_completion '$'separators\034i'' \
|
|
|
|
|
'$'separators\034in\035dir'' &&
|
|
|
|
|
test_path_completion '$'separators\034in\035dir/sep'' \
|
|
|
|
|
'$'separators\034in\035dir/sep\036in\037file'' &&
|
|
|
|
|
test_path_completion '$'separators\034in\035dir/sep\036i'' \
|
|
|
|
|
'$'separators\034in\035dir/sep\036in\037file''
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success FUNNYNAMES \
|
|
|
|
|
'__git_complete_index_file - removing repeated quoted path components' '
|
|
|
|
|
test_when_finished rm -r repeated-quoted &&
|
|
|
|
|
mkdir repeated-quoted && # A directory whose name in itself
|
|
|
|
|
# would not be quoted ...
|
|
|
|
|
>repeated-quoted/0-file &&
|
|
|
|
|
>repeated-quoted/1\"file && # ... but here the file makes the
|
|
|
|
|
# dirname quoted ...
|
|
|
|
|
>repeated-quoted/2-file &&
|
|
|
|
|
>repeated-quoted/3\"file && # ... and here, too.
|
|
|
|
|
|
|
|
|
|
# Still, we shold only list the directory name only once.
|
|
|
|
|
test_path_completion repeated repeated-quoted
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success 'teardown after path completion tests' '
|
|
|
|
|
rm -rf simple-dir "spaces in dir" árvíztűrő \
|
|
|
|
|
BS\\dir '$'separators\034in\035dir''
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
|
2015-05-10 14:50:18 +02:00
|
|
|
|
test_expect_success '__git_get_config_variables' '
|
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
|
name-1
|
|
|
|
|
name-2
|
|
|
|
|
EOF
|
|
|
|
|
test_config interesting.name-1 good &&
|
|
|
|
|
test_config interesting.name-2 good &&
|
|
|
|
|
test_config subsection.interesting.name-3 bad &&
|
|
|
|
|
__git_get_config_variables interesting >actual &&
|
|
|
|
|
test_cmp expect actual
|
|
|
|
|
'
|
|
|
|
|
|
2015-05-10 14:50:17 +02:00
|
|
|
|
test_expect_success '__git_pretty_aliases' '
|
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
|
author
|
|
|
|
|
hash
|
|
|
|
|
EOF
|
|
|
|
|
test_config pretty.author "%an %ae" &&
|
|
|
|
|
test_config pretty.hash %H &&
|
|
|
|
|
__git_pretty_aliases >actual &&
|
|
|
|
|
test_cmp expect actual
|
|
|
|
|
'
|
|
|
|
|
|
2012-04-11 23:57:03 +02:00
|
|
|
|
test_expect_success 'basic' '
|
2013-04-10 08:57:51 +02:00
|
|
|
|
run_completion "git " &&
|
2012-04-11 23:57:03 +02:00
|
|
|
|
# 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
|
2013-06-22 13:25:18 +02:00
|
|
|
|
--man-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
|
2018-02-09 12:01:48 +01:00
|
|
|
|
--detach Z
|
|
|
|
|
--track Z
|
|
|
|
|
--orphan=Z
|
2012-04-11 23:57:03 +02:00
|
|
|
|
--ours Z
|
|
|
|
|
--theirs Z
|
|
|
|
|
--merge Z
|
2018-02-09 12:01:48 +01:00
|
|
|
|
--conflict=Z
|
2012-04-11 23:57:03 +02:00
|
|
|
|
--patch Z
|
2017-10-24 15:19:31 +02:00
|
|
|
|
--ignore-skip-worktree-bits Z
|
2018-02-09 12:01:48 +01:00
|
|
|
|
--ignore-other-worktrees Z
|
2017-10-24 15:19:31 +02:00
|
|
|
|
--recurse-submodules Z
|
2018-02-09 12:01:48 +01:00
|
|
|
|
--progress Z
|
2018-06-06 11:41:39 +02:00
|
|
|
|
--no-quiet Z
|
|
|
|
|
--no-... Z
|
2012-04-11 23:57:03 +02:00
|
|
|
|
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 " &&
|
completion: fix completion after 'git -C <path>'
The main completion function finds the name of the git command by
iterating through all the words on the command line in search for the
first non-option-looking word. As it is not aware of 'git -C's
mandatory path argument, if the '-C <path>' option is present, 'path'
will be the first such word and it will be mistaken for a git command.
This breaks completion in various ways:
- If 'path' happens to match one of the commands supported by the
completion script, then options of that command will be offered.
- If 'path' doesn't match a supported command and doesn't contain any
characters not allowed in Bash identifier names, then the
completion script does basically nothing and Bash in turn falls
back to filename completion for all subsequent words.
- Otherwise, if 'path' does contain such an unallowed character, then
it leads to a more or less ugly error message in the middle of the
command line. The standard '/' directory separator is such a
character, and it happens to trigger one of the uglier errors:
$ git -C some/path <TAB>sh.exe": declare: `_git_some/path': not a valid identifier
error: invalid key: alias.some/path
Fix this by skipping 'git -C's mandatory path argument while iterating
over the words on the command line. Extend the relevant test with
this case and, while at it, with cases that needed similar treatment
in the past ('--git-dir', '-c', '--work-tree' and '--namespace').
Additionally, silence the standard error of the 'declare' builtins
looking for the completion function associated with the git command
and of the 'git config' query for the aliased command. So if git ever
learns a new option with a mandatory argument in the future, then,
though the completion script will again misbehave, at least the
command line will not be utterly disrupted by those error messages.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:22 +01:00
|
|
|
|
test_completion "git --no-replace-objects check" "checkout " &&
|
|
|
|
|
test_completion "git --git-dir some/path check" "checkout " &&
|
|
|
|
|
test_completion "git -c conf.var=value check" "checkout " &&
|
|
|
|
|
test_completion "git -C some/path check" "checkout " &&
|
|
|
|
|
test_completion "git --work-tree some/path check" "checkout " &&
|
|
|
|
|
test_completion "git --namespace name/space check" "checkout "
|
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
|
|
|
|
'
|
|
|
|
|
|
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 "
|
|
|
|
|
'
|
|
|
|
|
|
completion tests: add tests for the __git_refs() helper function
Check how __git_refs() lists refs in different scenarios, i.e.
- short and full refs,
- from a local or from a remote repository,
- remote specified via path, name or URL,
- with or without a repository specified on the command line,
- non-existing remote,
- unique remote branches for 'git checkout's tracking DWIMery,
- not in a git repository, and
- interesting combinations of the above.
Seven of these tests expect failure, mostly demonstrating bugs related
to listing refs from a remote repository:
- ignoring the repository specified on the command line (2 tests),
- listing refs from the wrong place when the name of a configured
remote happens to match a directory,
- listing only 'HEAD' but no short refs from a remote given as URL,
- listing 'HEAD' even from non-existing remotes (2 tests), and
- listing 'HEAD' when not in a repository.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:14 +01:00
|
|
|
|
test_expect_success 'setup for integration tests' '
|
2012-09-26 23:47:51 +02:00
|
|
|
|
echo content >file1 &&
|
|
|
|
|
echo more >file2 &&
|
2017-02-03 03:48:10 +01:00
|
|
|
|
git add file1 file2 &&
|
2012-09-26 23:47:51 +02:00
|
|
|
|
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
|
|
|
|
|
'
|
|
|
|
|
|
completion: respect 'git -C <path>'
'git -C <path>' option(s) on the command line should be taken into
account during completion, because
- like '--git-dir=<path>', it can lead us to a different repository,
- a few git commands executed in the completion script do care about
in which directory they are executed, and
- the command for which we are providing completion might care about
in which directory it will be executed.
However, unlike '--git-dir=<path>', the '-C <path>' option can be
specified multiple times and their effect is cumulative, so we can't
just store a single '<path>' in a variable. Nor can we simply
concatenate a path from '-C <path1> -C <path2> ...', because e.g. (in
an arguably pathological corner case) a relative path might be
followed by an absolute path.
Instead, store all '-C <path>' options word by word in the
$__git_C_args array in the main git completion function, and pass this
array, if present, to 'git rev-parse --absolute-git-dir' when
discovering the repository in __gitdir(), and let it take care of
multiple options, relative paths, absolute paths and everything.
Also pass all '-C <path> options via the $__git_C_args array to those
git executions which require a worktree and for which it matters from
which directory they are executed from. There are only three such
cases:
- 'git diff-index' and 'git ls-files' in __git_ls_files_helper()
used for git-aware filename completion, and
- the 'git ls-tree' used for completing the 'ref:path' notation.
The other git commands executed in the completion script don't need
these '-C <path>' options, because __gitdir() already took those
options into account. It would not hurt them, either, but let's not
induce unnecessary code churn.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 03:48:24 +01:00
|
|
|
|
test_expect_success 'git -C <path> checkout uses the right repo' '
|
|
|
|
|
test_completion "git -C subdir -C subsubdir -C .. -C ../otherrepo checkout b" <<-\EOF
|
|
|
|
|
branch-in-other Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
2012-09-26 23:47:51 +02:00
|
|
|
|
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" &&
|
2017-02-03 03:48:10 +01:00
|
|
|
|
git add "name with spaces" &&
|
2012-09-26 23:51:06 +02:00
|
|
|
|
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
|
|
|
|
|
'
|
|
|
|
|
|
2013-04-10 08:57:55 +02:00
|
|
|
|
test_expect_success 'complete tree filename with metacharacters' '
|
2012-09-26 23:51:06 +02:00
|
|
|
|
echo content >"name with \${meta}" &&
|
2017-02-03 03:48:10 +01:00
|
|
|
|
git add "name with \${meta}" &&
|
2012-09-26 23:51:06 +02:00
|
|
|
|
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 "
|
|
|
|
|
'
|
|
|
|
|
|
2013-04-27 22:09:59 +02:00
|
|
|
|
test_expect_success 'complete files' '
|
|
|
|
|
git init tmp && cd tmp &&
|
|
|
|
|
test_when_finished "cd .. && rm -rf tmp" &&
|
|
|
|
|
|
|
|
|
|
echo "expected" > .gitignore &&
|
|
|
|
|
echo "out" >> .gitignore &&
|
t9902-completion: ignore COMPREPLY element order in some tests
The order or possible completion words in the COMPREPLY array doesn't
actually matter, as long as all the right words are in there, because
Bash will sort them anyway. Yet, our tests looking at the elements of
COMPREPLY always expect them to be in a specific order.
Now, this hasn't been an issue before, but the next patch is about to
optimize a bit more our git-aware path completion, and as a harmless
side effect the order of elements in COMPREPLY will change. Worse,
the order will be downright undefined, because after the next patch
path components will come directly from iterating through an
associative array in 'awk', and the order of iteration over the
elements in those arrays is undefined, and indeed different 'awk'
implementations produce different order. Consequently, we can't get
away with simply adjusting the expected results in the affected tests.
Modify the 'test_completion' helper function to sort both the expected
and the actual results, i.e. the elements in COMPREPLY, before
comparing them, so the tests using this helper function will work
regardless of the order of elements.
Note that this change still leaves a bunch of tests depending on the
order of elements in COMPREPLY, tests that focus on a specific helper
function and therefore don't use the 'test_completion' helper. I
would rather deal with those later, when (if ever) the need actually
arises, than create unnecessary code churn now.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-17 00:41:12 +02:00
|
|
|
|
echo "out_sorted" >> .gitignore &&
|
2013-04-27 22:09:59 +02:00
|
|
|
|
|
|
|
|
|
git add .gitignore &&
|
|
|
|
|
test_completion "git commit " ".gitignore" &&
|
|
|
|
|
|
|
|
|
|
git commit -m ignore &&
|
|
|
|
|
|
|
|
|
|
touch new &&
|
|
|
|
|
test_completion "git add " "new" &&
|
|
|
|
|
|
|
|
|
|
git add new &&
|
|
|
|
|
git commit -a -m new &&
|
|
|
|
|
test_completion "git add " "" &&
|
|
|
|
|
|
|
|
|
|
git mv new modified &&
|
|
|
|
|
echo modify > modified &&
|
|
|
|
|
test_completion "git add " "modified" &&
|
|
|
|
|
|
|
|
|
|
touch untracked &&
|
|
|
|
|
|
|
|
|
|
: TODO .gitignore should not be here &&
|
|
|
|
|
test_completion "git rm " <<-\EOF &&
|
|
|
|
|
.gitignore
|
|
|
|
|
modified
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
test_completion "git clean " "untracked" &&
|
|
|
|
|
|
|
|
|
|
: TODO .gitignore should not be here &&
|
|
|
|
|
test_completion "git mv " <<-\EOF &&
|
|
|
|
|
.gitignore
|
|
|
|
|
modified
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
mkdir dir &&
|
|
|
|
|
touch dir/file-in-dir &&
|
|
|
|
|
git add dir/file-in-dir &&
|
|
|
|
|
git commit -m dir &&
|
|
|
|
|
|
|
|
|
|
mkdir untracked-dir &&
|
|
|
|
|
|
|
|
|
|
: TODO .gitignore should not be here &&
|
|
|
|
|
test_completion "git mv modified " <<-\EOF &&
|
|
|
|
|
.gitignore
|
|
|
|
|
dir
|
|
|
|
|
modified
|
|
|
|
|
untracked
|
|
|
|
|
untracked-dir
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
test_completion "git commit " "modified" &&
|
|
|
|
|
|
|
|
|
|
: TODO .gitignore should not be here &&
|
2015-03-20 11:06:15 +01:00
|
|
|
|
test_completion "git ls-files " <<-\EOF &&
|
2013-04-27 22:09:59 +02:00
|
|
|
|
.gitignore
|
|
|
|
|
dir
|
|
|
|
|
modified
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
|
|
touch momified &&
|
|
|
|
|
test_completion "git add mom" "momified"
|
|
|
|
|
'
|
|
|
|
|
|
2014-06-12 20:49:29 +02:00
|
|
|
|
test_expect_success "completion uses <cmd> completion for alias: !sh -c 'git <cmd> ...'" '
|
|
|
|
|
test_config alias.co "!sh -c '"'"'git checkout ...'"'"'" &&
|
|
|
|
|
test_completion "git co m" <<-\EOF
|
|
|
|
|
master Z
|
|
|
|
|
mybranch Z
|
|
|
|
|
mytag Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success 'completion uses <cmd> completion for alias: !f () { VAR=val git <cmd> ... }' '
|
|
|
|
|
test_config alias.co "!f () { VAR=val git checkout ... ; } f" &&
|
|
|
|
|
test_completion "git co m" <<-\EOF
|
|
|
|
|
master Z
|
|
|
|
|
mybranch Z
|
|
|
|
|
mytag Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success 'completion used <cmd> completion for alias: !f() { : git <cmd> ; ... }' '
|
|
|
|
|
test_config alias.co "!f() { : git checkout ; if ... } f" &&
|
|
|
|
|
test_completion "git co m" <<-\EOF
|
|
|
|
|
master Z
|
|
|
|
|
mybranch Z
|
|
|
|
|
mytag Z
|
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
2018-03-24 21:35:22 +01:00
|
|
|
|
test_expect_success 'completion without explicit _git_xxx function' '
|
|
|
|
|
test_completion "git version --" <<-\EOF
|
|
|
|
|
--build-options Z
|
2018-05-27 10:38:26 +02:00
|
|
|
|
--no-build-options Z
|
2018-03-24 21:35:22 +01:00
|
|
|
|
EOF
|
|
|
|
|
'
|
|
|
|
|
|
2013-04-27 22:10:00 +02:00
|
|
|
|
test_expect_failure 'complete with tilde expansion' '
|
|
|
|
|
git init tmp && cd tmp &&
|
|
|
|
|
test_when_finished "cd .. && rm -rf tmp" &&
|
|
|
|
|
|
|
|
|
|
touch ~/tmp/file &&
|
|
|
|
|
|
|
|
|
|
test_completion "git add ~/tmp/" "~/tmp/file"
|
|
|
|
|
'
|
|
|
|
|
|
completion: expand "push --delete <remote> <ref>" for refs on that <remote>
Change the completion of "push --delete <remote> <ref>" to complete
refs on that <remote>, not all refs.
Before this cloning git.git and doing "git push --delete origin
p<TAB>" will complete nothing, since a fresh clone of git.git will
have no "pu" branch, whereas origin/p<TAB> will uselessly complete
origin/pu, but fully qualified references aren't accepted by
"--delete".
Now p<TAB> will complete as "pu". The completion of giving --delete
later, e.g. "git push origin --delete p<TAB>" remains unchanged, this
is a bug, but is a general existing limitation of the bash completion,
and not how git-push is documented, so I'm not fixing that case, but
adding a failing TODO test for it.
The testing code was supplied by SZEDER Gábor in
<20170421122832.24617-1-szeder.dev@gmail.com> with minor setup
modifications on my part.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Reviewed-by: SZEDER Gábor <szeder.dev@gmail.com>
Test-code-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-04-22 19:55:04 +02:00
|
|
|
|
test_expect_success 'setup other remote for remote reference completion' '
|
|
|
|
|
git remote add other otherrepo &&
|
|
|
|
|
git fetch other
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
for flag in -d --delete
|
|
|
|
|
do
|
|
|
|
|
test_expect_success "__git_complete_remote_or_refspec - push $flag other" '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
master-in-other Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
words=(git push '$flag' other ma) &&
|
|
|
|
|
cword=${#words[@]} cur=${words[cword-1]} &&
|
|
|
|
|
__git_complete_remote_or_refspec &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_failure "__git_complete_remote_or_refspec - push other $flag" '
|
|
|
|
|
sed -e "s/Z$//" >expected <<-EOF &&
|
|
|
|
|
master-in-other Z
|
|
|
|
|
EOF
|
|
|
|
|
(
|
|
|
|
|
words=(git push other '$flag' ma) &&
|
|
|
|
|
cword=${#words[@]} cur=${words[cword-1]} &&
|
|
|
|
|
__git_complete_remote_or_refspec &&
|
|
|
|
|
print_comp
|
|
|
|
|
) &&
|
|
|
|
|
test_cmp expected out
|
|
|
|
|
'
|
|
|
|
|
done
|
|
|
|
|
|
completion: clear cached --options when sourcing the completion script
The established way to update the completion script in an already
running shell is to simply source it again: this brings in any new
--options and features, and clears caching variables. E.g. it clears
the variables caching the list of (all|porcelain) git commands, so
when they are later lazy-initialized again, then they will list and
cache any newly installed commmands as well.
Unfortunately, since d401f3debc (git-completion.bash: introduce
__gitcomp_builtin, 2018-02-09) and subsequent patches this doesn't
work for a lot of git commands' options. To eliminate a lot of
hard-to-maintain hard-coded lists of options, those commits changed
the completion script to use a bunch of programmatically created and
lazy-initialized variables to cache the options of those builtin
porcelain commands that use parse-options. These variables are not
cleared upon sourcing the completion script, therefore they continue
caching the old lists of options, even when some commands recently
learned new options or when deprecated options were removed.
Always 'unset' these variables caching the options of builtin commands
when sourcing the completion script.
Redirect 'unset's stderr to /dev/null, because ZSH's 'unset' complains
if it's invoked without any arguments, i.e. no variables caching
builtin's options are set. This can happen, if someone were to source
the completion script twice without completing any --options in
between. Bash stays silent in this case.
Add tests to ensure that these variables are indeed cleared when the
completion script is sourced; not just the variables caching options,
but all other caching variables, i.e. the variables caching commands,
porcelain commands and merge strategies as well.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-03-22 15:16:04 +01:00
|
|
|
|
test_expect_success 'sourcing the completion script clears cached commands' '
|
|
|
|
|
__git_compute_all_commands &&
|
|
|
|
|
verbose test -n "$__git_all_commands" &&
|
|
|
|
|
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
|
|
|
|
|
verbose test -z "$__git_all_commands"
|
|
|
|
|
'
|
|
|
|
|
|
2018-03-23 18:40:06 +01:00
|
|
|
|
test_expect_success !GETTEXT_POISON 'sourcing the completion script clears cached merge strategies' '
|
completion: clear cached --options when sourcing the completion script
The established way to update the completion script in an already
running shell is to simply source it again: this brings in any new
--options and features, and clears caching variables. E.g. it clears
the variables caching the list of (all|porcelain) git commands, so
when they are later lazy-initialized again, then they will list and
cache any newly installed commmands as well.
Unfortunately, since d401f3debc (git-completion.bash: introduce
__gitcomp_builtin, 2018-02-09) and subsequent patches this doesn't
work for a lot of git commands' options. To eliminate a lot of
hard-to-maintain hard-coded lists of options, those commits changed
the completion script to use a bunch of programmatically created and
lazy-initialized variables to cache the options of those builtin
porcelain commands that use parse-options. These variables are not
cleared upon sourcing the completion script, therefore they continue
caching the old lists of options, even when some commands recently
learned new options or when deprecated options were removed.
Always 'unset' these variables caching the options of builtin commands
when sourcing the completion script.
Redirect 'unset's stderr to /dev/null, because ZSH's 'unset' complains
if it's invoked without any arguments, i.e. no variables caching
builtin's options are set. This can happen, if someone were to source
the completion script twice without completing any --options in
between. Bash stays silent in this case.
Add tests to ensure that these variables are indeed cleared when the
completion script is sourced; not just the variables caching options,
but all other caching variables, i.e. the variables caching commands,
porcelain commands and merge strategies as well.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-03-22 15:16:04 +01:00
|
|
|
|
__git_compute_merge_strategies &&
|
|
|
|
|
verbose test -n "$__git_merge_strategies" &&
|
|
|
|
|
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
|
|
|
|
|
verbose test -z "$__git_merge_strategies"
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
test_expect_success 'sourcing the completion script clears cached --options' '
|
|
|
|
|
__gitcomp_builtin checkout &&
|
|
|
|
|
verbose test -n "$__gitcomp_builtin_checkout" &&
|
|
|
|
|
__gitcomp_builtin notes_edit &&
|
|
|
|
|
verbose test -n "$__gitcomp_builtin_notes_edit" &&
|
|
|
|
|
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
|
|
|
|
|
verbose test -z "$__gitcomp_builtin_checkout" &&
|
|
|
|
|
verbose test -z "$__gitcomp_builtin_notes_edit"
|
|
|
|
|
'
|
|
|
|
|
|
2012-04-11 23:57:03 +02:00
|
|
|
|
test_done
|