2007-06-06 07:01:21 +00:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='test git rev-parse'
|
2020-11-18 23:44:21 +00:00
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
tests: mark tests relying on the current default for `init.defaultBranch`
In addition to the manual adjustment to let the `linux-gcc` CI job run
the test suite with `master` and then with `main`, this patch makes sure
that GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME is set in all test scripts
that currently rely on the initial branch name being `master by default.
To determine which test scripts to mark up, the first step was to
force-set the default branch name to `master` in
- all test scripts that contain the keyword `master`,
- t4211, which expects `t/t4211/history.export` with a hard-coded ref to
initialize the default branch,
- t5560 because it sources `t/t556x_common` which uses `master`,
- t8002 and t8012 because both source `t/annotate-tests.sh` which also
uses `master`)
This trick was performed by this command:
$ sed -i '/^ *\. \.\/\(test-lib\|lib-\(bash\|cvs\|git-svn\)\|gitweb-lib\)\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' $(git grep -l master t/t[0-9]*.sh) \
t/t4211*.sh t/t5560*.sh t/t8002*.sh t/t8012*.sh
After that, careful, manual inspection revealed that some of the test
scripts containing the needle `master` do not actually rely on a
specific default branch name: either they mention `master` only in a
comment, or they initialize that branch specificially, or they do not
actually refer to the current default branch. Therefore, the
aforementioned modification was undone in those test scripts thusly:
$ git checkout HEAD -- \
t/t0027-auto-crlf.sh t/t0060-path-utils.sh \
t/t1011-read-tree-sparse-checkout.sh \
t/t1305-config-include.sh t/t1309-early-config.sh \
t/t1402-check-ref-format.sh t/t1450-fsck.sh \
t/t2024-checkout-dwim.sh \
t/t2106-update-index-assume-unchanged.sh \
t/t3040-subprojects-basic.sh t/t3301-notes.sh \
t/t3308-notes-merge.sh t/t3423-rebase-reword.sh \
t/t3436-rebase-more-options.sh \
t/t4015-diff-whitespace.sh t/t4257-am-interactive.sh \
t/t5323-pack-redundant.sh t/t5401-update-hooks.sh \
t/t5511-refspec.sh t/t5526-fetch-submodules.sh \
t/t5529-push-errors.sh t/t5530-upload-pack-error.sh \
t/t5548-push-porcelain.sh \
t/t5552-skipping-fetch-negotiator.sh \
t/t5572-pull-submodule.sh t/t5608-clone-2gb.sh \
t/t5614-clone-submodules-shallow.sh \
t/t7508-status.sh t/t7606-merge-custom.sh \
t/t9302-fast-import-unpack-limit.sh
We excluded one set of test scripts in these commands, though: the range
of `git p4` tests. The reason? `git p4` stores the (foreign) remote
branch in the branch called `p4/master`, which is obviously not the
default branch. Manual analysis revealed that only five of these tests
actually require a specific default branch name to pass; They were
modified thusly:
$ sed -i '/^ *\. \.\/lib-git-p4\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' t/t980[0167]*.sh t/t9811*.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-18 23:44:19 +00:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
2022-08-31 23:14:08 +00:00
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
2007-06-06 07:01:21 +00:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
2020-12-13 00:25:29 +00:00
|
|
|
test_one () {
|
|
|
|
dir="$1" &&
|
|
|
|
expect="$2" &&
|
|
|
|
shift &&
|
|
|
|
shift &&
|
|
|
|
echo "$expect" >expect &&
|
|
|
|
git -C "$dir" rev-parse "$@" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
}
|
|
|
|
|
rev-parse: add '--absolute-git-dir' option
The output of 'git rev-parse --git-dir' can be either a relative or an
absolute path, depending on whether the current working directory is
at the top of the worktree or the .git directory or not, or how the
path to the repository is specified via the '--git-dir=<path>' option
or the $GIT_DIR environment variable. And if that output is a
relative path, then it is relative to the directory where any 'git
-C <path>' options might have led us.
This doesn't matter at all for regular scripts, because the git
wrapper automatically takes care of changing directories according to
the '-C <path>' options, and the scripts can then simply follow any
path returned by 'git rev-parse --git-dir', even if it's a relative
path.
Our Bash completion script, however, is unique in that it must run
directly in the user's interactive shell environment. This means that
it's not executed through the git wrapper and would have to take care
of any '-C <path> options on its own, and it can't just change
directories as it pleases. Consequently, adding support for taking
any '-C <path>' options on the command line into account during
completion turned out to be considerably more difficult, error prone
and required more subshells and git processes when it had to cope with
a relative path to the .git directory.
Help this rather special use case and teach 'git rev-parse' a new
'--absolute-git-dir' option which always outputs a canonicalized
absolute path to the .git directory, regardless of whether the path is
discovered automatically or is specified via $GIT_DIR or 'git
--git-dir=<path>'.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 02:48:23 +00:00
|
|
|
# usage: [options] label is-bare is-inside-git is-inside-work prefix git-dir absolute-git-dir
|
2016-05-18 20:15:42 +00:00
|
|
|
test_rev_parse () {
|
2016-05-18 20:15:43 +00:00
|
|
|
d=
|
2016-05-18 20:15:44 +00:00
|
|
|
bare=
|
2016-05-18 20:15:45 +00:00
|
|
|
gitdir=
|
2016-05-18 20:15:43 +00:00
|
|
|
while :
|
|
|
|
do
|
|
|
|
case "$1" in
|
|
|
|
-C) d="$2"; shift; shift ;;
|
2016-05-18 20:15:44 +00:00
|
|
|
-b) case "$2" in
|
|
|
|
[tfu]*) bare="$2"; shift; shift ;;
|
|
|
|
*) error "test_rev_parse: bogus core.bare value '$2'" ;;
|
|
|
|
esac ;;
|
2016-05-18 20:15:45 +00:00
|
|
|
-g) gitdir="$2"; shift; shift ;;
|
2016-05-18 20:15:43 +00:00
|
|
|
-*) error "test_rev_parse: unrecognized option '$1'" ;;
|
|
|
|
*) break ;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
2007-06-06 07:01:21 +00:00
|
|
|
name=$1
|
|
|
|
shift
|
|
|
|
|
2016-05-18 20:15:42 +00:00
|
|
|
for o in --is-bare-repository \
|
|
|
|
--is-inside-git-dir \
|
|
|
|
--is-inside-work-tree \
|
|
|
|
--show-prefix \
|
rev-parse: add '--absolute-git-dir' option
The output of 'git rev-parse --git-dir' can be either a relative or an
absolute path, depending on whether the current working directory is
at the top of the worktree or the .git directory or not, or how the
path to the repository is specified via the '--git-dir=<path>' option
or the $GIT_DIR environment variable. And if that output is a
relative path, then it is relative to the directory where any 'git
-C <path>' options might have led us.
This doesn't matter at all for regular scripts, because the git
wrapper automatically takes care of changing directories according to
the '-C <path>' options, and the scripts can then simply follow any
path returned by 'git rev-parse --git-dir', even if it's a relative
path.
Our Bash completion script, however, is unique in that it must run
directly in the user's interactive shell environment. This means that
it's not executed through the git wrapper and would have to take care
of any '-C <path> options on its own, and it can't just change
directories as it pleases. Consequently, adding support for taking
any '-C <path>' options on the command line into account during
completion turned out to be considerably more difficult, error prone
and required more subshells and git processes when it had to cope with
a relative path to the .git directory.
Help this rather special use case and teach 'git rev-parse' a new
'--absolute-git-dir' option which always outputs a canonicalized
absolute path to the .git directory, regardless of whether the path is
discovered automatically or is specified via $GIT_DIR or 'git
--git-dir=<path>'.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 02:48:23 +00:00
|
|
|
--git-dir \
|
|
|
|
--absolute-git-dir
|
2016-05-18 20:15:42 +00:00
|
|
|
do
|
|
|
|
test $# -eq 0 && break
|
|
|
|
expect="$1"
|
|
|
|
test_expect_success "$name: $o" '
|
2016-05-18 20:15:45 +00:00
|
|
|
if test -n "$gitdir"
|
|
|
|
then
|
|
|
|
test_when_finished "unset GIT_DIR" &&
|
|
|
|
GIT_DIR="$gitdir" &&
|
|
|
|
export GIT_DIR
|
|
|
|
fi &&
|
|
|
|
|
2016-05-18 20:15:44 +00:00
|
|
|
case "$bare" in
|
|
|
|
t*) test_config ${d:+-C} ${d:+"$d"} core.bare true ;;
|
|
|
|
f*) test_config ${d:+-C} ${d:+"$d"} core.bare false ;;
|
|
|
|
u*) test_unconfig ${d:+-C} ${d:+"$d"} core.bare ;;
|
|
|
|
esac &&
|
|
|
|
|
2016-05-18 20:15:42 +00:00
|
|
|
echo "$expect" >expect &&
|
2016-05-18 20:15:43 +00:00
|
|
|
git ${d:+-C} ${d:+"$d"} rev-parse $o >actual &&
|
2016-05-18 20:15:42 +00:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
shift
|
|
|
|
done
|
2007-06-06 07:01:21 +00:00
|
|
|
}
|
|
|
|
|
2009-02-14 16:16:28 +00:00
|
|
|
ROOT=$(pwd)
|
2007-08-05 13:12:53 +00:00
|
|
|
|
2016-05-17 19:36:26 +00:00
|
|
|
test_expect_success 'setup' '
|
|
|
|
mkdir -p sub/dir work &&
|
2020-12-13 00:25:29 +00:00
|
|
|
cp -R .git repo.git &&
|
|
|
|
git checkout -B main &&
|
|
|
|
test_commit abc &&
|
|
|
|
git checkout -b side &&
|
|
|
|
test_commit def &&
|
|
|
|
git checkout main &&
|
|
|
|
git worktree add worktree side
|
2016-05-17 19:36:26 +00:00
|
|
|
'
|
|
|
|
|
rev-parse: add '--absolute-git-dir' option
The output of 'git rev-parse --git-dir' can be either a relative or an
absolute path, depending on whether the current working directory is
at the top of the worktree or the .git directory or not, or how the
path to the repository is specified via the '--git-dir=<path>' option
or the $GIT_DIR environment variable. And if that output is a
relative path, then it is relative to the directory where any 'git
-C <path>' options might have led us.
This doesn't matter at all for regular scripts, because the git
wrapper automatically takes care of changing directories according to
the '-C <path>' options, and the scripts can then simply follow any
path returned by 'git rev-parse --git-dir', even if it's a relative
path.
Our Bash completion script, however, is unique in that it must run
directly in the user's interactive shell environment. This means that
it's not executed through the git wrapper and would have to take care
of any '-C <path> options on its own, and it can't just change
directories as it pleases. Consequently, adding support for taking
any '-C <path>' options on the command line into account during
completion turned out to be considerably more difficult, error prone
and required more subshells and git processes when it had to cope with
a relative path to the .git directory.
Help this rather special use case and teach 'git rev-parse' a new
'--absolute-git-dir' option which always outputs a canonicalized
absolute path to the .git directory, regardless of whether the path is
discovered automatically or is specified via $GIT_DIR or 'git
--git-dir=<path>'.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 02:48:23 +00:00
|
|
|
test_rev_parse toplevel false false true '' .git "$ROOT/.git"
|
2007-06-06 07:01:21 +00:00
|
|
|
|
rev-parse: add '--absolute-git-dir' option
The output of 'git rev-parse --git-dir' can be either a relative or an
absolute path, depending on whether the current working directory is
at the top of the worktree or the .git directory or not, or how the
path to the repository is specified via the '--git-dir=<path>' option
or the $GIT_DIR environment variable. And if that output is a
relative path, then it is relative to the directory where any 'git
-C <path>' options might have led us.
This doesn't matter at all for regular scripts, because the git
wrapper automatically takes care of changing directories according to
the '-C <path>' options, and the scripts can then simply follow any
path returned by 'git rev-parse --git-dir', even if it's a relative
path.
Our Bash completion script, however, is unique in that it must run
directly in the user's interactive shell environment. This means that
it's not executed through the git wrapper and would have to take care
of any '-C <path> options on its own, and it can't just change
directories as it pleases. Consequently, adding support for taking
any '-C <path>' options on the command line into account during
completion turned out to be considerably more difficult, error prone
and required more subshells and git processes when it had to cope with
a relative path to the .git directory.
Help this rather special use case and teach 'git rev-parse' a new
'--absolute-git-dir' option which always outputs a canonicalized
absolute path to the .git directory, regardless of whether the path is
discovered automatically or is specified via $GIT_DIR or 'git
--git-dir=<path>'.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 02:48:23 +00:00
|
|
|
test_rev_parse -C .git .git/ false true false '' . "$ROOT/.git"
|
|
|
|
test_rev_parse -C .git/objects .git/objects/ false true false '' "$ROOT/.git" "$ROOT/.git"
|
2007-06-06 07:01:21 +00:00
|
|
|
|
rev-parse: add '--absolute-git-dir' option
The output of 'git rev-parse --git-dir' can be either a relative or an
absolute path, depending on whether the current working directory is
at the top of the worktree or the .git directory or not, or how the
path to the repository is specified via the '--git-dir=<path>' option
or the $GIT_DIR environment variable. And if that output is a
relative path, then it is relative to the directory where any 'git
-C <path>' options might have led us.
This doesn't matter at all for regular scripts, because the git
wrapper automatically takes care of changing directories according to
the '-C <path>' options, and the scripts can then simply follow any
path returned by 'git rev-parse --git-dir', even if it's a relative
path.
Our Bash completion script, however, is unique in that it must run
directly in the user's interactive shell environment. This means that
it's not executed through the git wrapper and would have to take care
of any '-C <path> options on its own, and it can't just change
directories as it pleases. Consequently, adding support for taking
any '-C <path>' options on the command line into account during
completion turned out to be considerably more difficult, error prone
and required more subshells and git processes when it had to cope with
a relative path to the .git directory.
Help this rather special use case and teach 'git rev-parse' a new
'--absolute-git-dir' option which always outputs a canonicalized
absolute path to the .git directory, regardless of whether the path is
discovered automatically or is specified via $GIT_DIR or 'git
--git-dir=<path>'.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 02:48:23 +00:00
|
|
|
test_rev_parse -C sub/dir subdirectory false false true sub/dir/ "$ROOT/.git" "$ROOT/.git"
|
2007-06-06 07:01:21 +00:00
|
|
|
|
2016-05-18 20:15:44 +00:00
|
|
|
test_rev_parse -b t 'core.bare = true' true false false
|
2007-06-06 07:01:21 +00:00
|
|
|
|
2016-05-18 20:15:44 +00:00
|
|
|
test_rev_parse -b u 'core.bare undefined' false false true
|
2007-06-06 07:01:21 +00:00
|
|
|
|
|
|
|
|
rev-parse: add '--absolute-git-dir' option
The output of 'git rev-parse --git-dir' can be either a relative or an
absolute path, depending on whether the current working directory is
at the top of the worktree or the .git directory or not, or how the
path to the repository is specified via the '--git-dir=<path>' option
or the $GIT_DIR environment variable. And if that output is a
relative path, then it is relative to the directory where any 'git
-C <path>' options might have led us.
This doesn't matter at all for regular scripts, because the git
wrapper automatically takes care of changing directories according to
the '-C <path>' options, and the scripts can then simply follow any
path returned by 'git rev-parse --git-dir', even if it's a relative
path.
Our Bash completion script, however, is unique in that it must run
directly in the user's interactive shell environment. This means that
it's not executed through the git wrapper and would have to take care
of any '-C <path> options on its own, and it can't just change
directories as it pleases. Consequently, adding support for taking
any '-C <path>' options on the command line into account during
completion turned out to be considerably more difficult, error prone
and required more subshells and git processes when it had to cope with
a relative path to the .git directory.
Help this rather special use case and teach 'git rev-parse' a new
'--absolute-git-dir' option which always outputs a canonicalized
absolute path to the .git directory, regardless of whether the path is
discovered automatically or is specified via $GIT_DIR or 'git
--git-dir=<path>'.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 02:48:23 +00:00
|
|
|
test_rev_parse -C work -g ../.git -b f 'GIT_DIR=../.git, core.bare = false' false false true '' "../.git" "$ROOT/.git"
|
2007-06-06 07:01:21 +00:00
|
|
|
|
2016-05-18 20:15:45 +00:00
|
|
|
test_rev_parse -C work -g ../.git -b t 'GIT_DIR=../.git, core.bare = true' true false false ''
|
2007-06-06 07:01:21 +00:00
|
|
|
|
2016-05-18 20:15:45 +00:00
|
|
|
test_rev_parse -C work -g ../.git -b u 'GIT_DIR=../.git, core.bare undefined' false false true ''
|
2007-06-06 07:01:21 +00:00
|
|
|
|
|
|
|
|
rev-parse: add '--absolute-git-dir' option
The output of 'git rev-parse --git-dir' can be either a relative or an
absolute path, depending on whether the current working directory is
at the top of the worktree or the .git directory or not, or how the
path to the repository is specified via the '--git-dir=<path>' option
or the $GIT_DIR environment variable. And if that output is a
relative path, then it is relative to the directory where any 'git
-C <path>' options might have led us.
This doesn't matter at all for regular scripts, because the git
wrapper automatically takes care of changing directories according to
the '-C <path>' options, and the scripts can then simply follow any
path returned by 'git rev-parse --git-dir', even if it's a relative
path.
Our Bash completion script, however, is unique in that it must run
directly in the user's interactive shell environment. This means that
it's not executed through the git wrapper and would have to take care
of any '-C <path> options on its own, and it can't just change
directories as it pleases. Consequently, adding support for taking
any '-C <path>' options on the command line into account during
completion turned out to be considerably more difficult, error prone
and required more subshells and git processes when it had to cope with
a relative path to the .git directory.
Help this rather special use case and teach 'git rev-parse' a new
'--absolute-git-dir' option which always outputs a canonicalized
absolute path to the .git directory, regardless of whether the path is
discovered automatically or is specified via $GIT_DIR or 'git
--git-dir=<path>'.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-03 02:48:23 +00:00
|
|
|
test_rev_parse -C work -g ../repo.git -b f 'GIT_DIR=../repo.git, core.bare = false' false false true '' "../repo.git" "$ROOT/repo.git"
|
2007-06-06 07:01:21 +00:00
|
|
|
|
2016-05-18 20:15:45 +00:00
|
|
|
test_rev_parse -C work -g ../repo.git -b t 'GIT_DIR=../repo.git, core.bare = true' true false false ''
|
2007-06-06 07:01:21 +00:00
|
|
|
|
2016-05-18 20:15:45 +00:00
|
|
|
test_rev_parse -C work -g ../repo.git -b u 'GIT_DIR=../repo.git, core.bare undefined' false false true ''
|
2007-06-06 07:01:21 +00:00
|
|
|
|
2020-12-13 00:25:29 +00:00
|
|
|
test_expect_success 'rev-parse --path-format=absolute' '
|
|
|
|
test_one "." "$ROOT/.git" --path-format=absolute --git-dir &&
|
|
|
|
test_one "." "$ROOT/.git" --path-format=absolute --git-common-dir &&
|
|
|
|
test_one "sub/dir" "$ROOT/.git" --path-format=absolute --git-dir &&
|
|
|
|
test_one "sub/dir" "$ROOT/.git" --path-format=absolute --git-common-dir &&
|
|
|
|
test_one "worktree" "$ROOT/.git/worktrees/worktree" --path-format=absolute --git-dir &&
|
|
|
|
test_one "worktree" "$ROOT/.git" --path-format=absolute --git-common-dir &&
|
|
|
|
test_one "." "$ROOT" --path-format=absolute --show-toplevel &&
|
|
|
|
test_one "." "$ROOT/.git/objects" --path-format=absolute --git-path objects &&
|
|
|
|
test_one "." "$ROOT/.git/objects/foo/bar/baz" --path-format=absolute --git-path objects/foo/bar/baz
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'rev-parse --path-format=relative' '
|
|
|
|
test_one "." ".git" --path-format=relative --git-dir &&
|
|
|
|
test_one "." ".git" --path-format=relative --git-common-dir &&
|
|
|
|
test_one "sub/dir" "../../.git" --path-format=relative --git-dir &&
|
|
|
|
test_one "sub/dir" "../../.git" --path-format=relative --git-common-dir &&
|
|
|
|
test_one "worktree" "../.git/worktrees/worktree" --path-format=relative --git-dir &&
|
|
|
|
test_one "worktree" "../.git" --path-format=relative --git-common-dir &&
|
|
|
|
test_one "." "./" --path-format=relative --show-toplevel &&
|
|
|
|
test_one "." ".git/objects" --path-format=relative --git-path objects &&
|
|
|
|
test_one "." ".git/objects/foo/bar/baz" --path-format=relative --git-path objects/foo/bar/baz
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '--path-format=relative does not affect --absolute-git-dir' '
|
|
|
|
git rev-parse --path-format=relative --absolute-git-dir >actual &&
|
|
|
|
echo "$ROOT/.git" >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '--path-format can change in the middle of the command line' '
|
|
|
|
git rev-parse --path-format=absolute --git-dir --path-format=relative --git-path objects/foo/bar >actual &&
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
$ROOT/.git
|
|
|
|
.git/objects/foo/bar
|
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2021-05-17 08:02:42 +00:00
|
|
|
test_expect_success '--path-format does not segfault without an argument' '
|
|
|
|
test_must_fail git rev-parse --path-format
|
|
|
|
'
|
|
|
|
|
2017-02-17 16:59:02 +00:00
|
|
|
test_expect_success 'git-common-dir from worktree root' '
|
|
|
|
echo .git >expect &&
|
|
|
|
git rev-parse --git-common-dir >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
rev-parse: fix several options when running in a subdirectory
In addition to making git_path() aware of certain file names that need
to be handled differently e.g. when running in worktrees, the commit
557bd833bb (git_path(): be aware of file relocation in $GIT_DIR,
2014-11-30) also snuck in a new option for `git rev-parse`:
`--git-path`.
On the face of it, there is no obvious bug in that commit's diff: it
faithfully calls git_path() on the argument and prints it out, i.e. `git
rev-parse --git-path <filename>` has the same precise behavior as
calling `git_path("<filename>")` in C.
The problem lies deeper, much deeper. In hindsight (which is always
unfair), implementing the .git/ directory discovery in
`setup_git_directory()` by changing the working directory may have
allowed us to avoid passing around a struct that contains information
about the current repository, but it bought us many, many problems.
In this case, when being called in a subdirectory, `git rev-parse`
changes the working directory to the top-level directory before calling
`git_path()`. In the new working directory, the result is correct. But
in the working directory of the calling script, it is incorrect.
Example: when calling `git rev-parse --git-path HEAD` in, say, the
Documentation/ subdirectory of Git's own source code, the string
`.git/HEAD` is printed.
Side note: that bug is hidden when running in a subdirectory of a
worktree that was added by the `git worktree` command: in that case, the
(correct) absolute path of the `HEAD` file is printed.
In the interest of time, this patch does not go the "correct" route to
introduce a struct with repository information (and removing global
state in the process), instead this patch chooses to detect when the
command was called in a subdirectory and forces the result to be an
absolute path.
While at it, we are also fixing the output of --git-common-dir and
--shared-index-path.
Lastly, please note that we reuse the same strbuf for all of the
relative_path() calls; this avoids frequent allocation (and duplicated
code), and it does not risk memory leaks, for two reasons: 1) the
cmd_rev_parse() function does not return anywhere between the use of
the new strbuf instance and its final release, and 2) git-rev-parse is
one of these "one-shot" programs in Git, i.e. it exits after running
for a very short time, meaning that all allocated memory is released
with the exit() call anyway.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-17 16:59:06 +00:00
|
|
|
test_expect_success 'git-common-dir inside sub-dir' '
|
2017-02-17 16:59:02 +00:00
|
|
|
mkdir -p path/to/child &&
|
|
|
|
test_when_finished "rm -rf path" &&
|
|
|
|
echo "$(git -C path/to/child rev-parse --show-cdup).git" >expect &&
|
|
|
|
git -C path/to/child rev-parse --git-common-dir >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'git-path from worktree root' '
|
|
|
|
echo .git/objects >expect &&
|
|
|
|
git rev-parse --git-path objects >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
rev-parse: fix several options when running in a subdirectory
In addition to making git_path() aware of certain file names that need
to be handled differently e.g. when running in worktrees, the commit
557bd833bb (git_path(): be aware of file relocation in $GIT_DIR,
2014-11-30) also snuck in a new option for `git rev-parse`:
`--git-path`.
On the face of it, there is no obvious bug in that commit's diff: it
faithfully calls git_path() on the argument and prints it out, i.e. `git
rev-parse --git-path <filename>` has the same precise behavior as
calling `git_path("<filename>")` in C.
The problem lies deeper, much deeper. In hindsight (which is always
unfair), implementing the .git/ directory discovery in
`setup_git_directory()` by changing the working directory may have
allowed us to avoid passing around a struct that contains information
about the current repository, but it bought us many, many problems.
In this case, when being called in a subdirectory, `git rev-parse`
changes the working directory to the top-level directory before calling
`git_path()`. In the new working directory, the result is correct. But
in the working directory of the calling script, it is incorrect.
Example: when calling `git rev-parse --git-path HEAD` in, say, the
Documentation/ subdirectory of Git's own source code, the string
`.git/HEAD` is printed.
Side note: that bug is hidden when running in a subdirectory of a
worktree that was added by the `git worktree` command: in that case, the
(correct) absolute path of the `HEAD` file is printed.
In the interest of time, this patch does not go the "correct" route to
introduce a struct with repository information (and removing global
state in the process), instead this patch chooses to detect when the
command was called in a subdirectory and forces the result to be an
absolute path.
While at it, we are also fixing the output of --git-common-dir and
--shared-index-path.
Lastly, please note that we reuse the same strbuf for all of the
relative_path() calls; this avoids frequent allocation (and duplicated
code), and it does not risk memory leaks, for two reasons: 1) the
cmd_rev_parse() function does not return anywhere between the use of
the new strbuf instance and its final release, and 2) git-rev-parse is
one of these "one-shot" programs in Git, i.e. it exits after running
for a very short time, meaning that all allocated memory is released
with the exit() call anyway.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-02-17 16:59:06 +00:00
|
|
|
test_expect_success 'git-path inside sub-dir' '
|
2017-02-17 16:59:02 +00:00
|
|
|
mkdir -p path/to/child &&
|
|
|
|
test_when_finished "rm -rf path" &&
|
|
|
|
echo "$(git -C path/to/child rev-parse --show-cdup).git/objects" >expect &&
|
|
|
|
git -C path/to/child rev-parse --git-path objects >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2017-09-18 17:04:29 +00:00
|
|
|
test_expect_success 'rev-parse --is-shallow-repository in shallow repo' '
|
|
|
|
test_commit test_commit &&
|
|
|
|
echo true >expect &&
|
|
|
|
git clone --depth 1 --no-local . shallow &&
|
|
|
|
test_when_finished "rm -rf shallow" &&
|
|
|
|
git -C shallow rev-parse --is-shallow-repository >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'rev-parse --is-shallow-repository in non-shallow repo' '
|
|
|
|
echo false >expect &&
|
|
|
|
git rev-parse --is-shallow-repository >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2019-10-28 00:58:55 +00:00
|
|
|
test_expect_success 'rev-parse --show-object-format in repo' '
|
tests: make 'test_oid' print trailing newline
Unlike other test helper functions, 'test_oid' doesn't terminate its
output with a LF, but, alas, the reason for this, if any, is not
mentioned in 2c02b110da (t: add test functions to translate
hash-related values, 2018-09-13)).
Now, in the vast majority of cases 'test_oid' is invoked in a command
substitution that is part of a heredoc or supplies an argument to a
command or the value to a variable, and the command substitution would
chop off any trailing LFs, so in these cases the lack or presence of a
trailing LF in its output doesn't matter. However:
- There appear to be only three cases where 'test_oid' is not
invoked in a command substitution:
$ git grep '\stest_oid ' -- ':/t/*.sh'
t0000-basic.sh: test_oid zero >actual &&
t0000-basic.sh: test_oid zero >actual &&
t0000-basic.sh: test_oid zero >actual &&
These are all in test cases checking that 'test_oid' actually
works, and that the size of its output matches the size of the
corresponding hash function with conditions like
test $(wc -c <actual) -eq 40
In these cases the lack of trailing LF does actually matter,
though they could be trivially updated to account for the presence
of a trailing LF.
- There are also a few cases where the lack of trailing LF in
'test_oid's output actually hurts, because tests need to compare
its output with LF terminated file contents, forcing developers to
invoke it as 'echo $(test_oid ...)' to append the missing LF:
$ git grep 'echo "\?$(test_oid ' -- ':/t/*.sh'
t1302-repo-version.sh: echo $(test_oid version) >expect &&
t1500-rev-parse.sh: echo "$(test_oid algo)" >expect &&
t4044-diff-index-unique-abbrev.sh: echo "$(test_oid val1)" > foo &&
t4044-diff-index-unique-abbrev.sh: echo "$(test_oid val2)" > foo &&
t5313-pack-bounds-checks.sh: echo $(test_oid oidfff) >file &&
And there is yet another similar case in an in-flight topic at:
https://public-inbox.org/git/813e81a058227bd373cec802e443fcd677042fb4.1670862677.git.gitgitgadget@gmail.com/
Arguably we would be better off if 'test_oid' terminated its output
with a LF. So let's update 'test_oid' accordingly, update its tests
in t0000 to account for the extra character in those size tests, and
remove the now unnecessary 'echo $(...)' command substitutions around
'test_oid' invocations as well.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-12-18 16:29:05 +00:00
|
|
|
test_oid algo >expect &&
|
2019-10-28 00:58:55 +00:00
|
|
|
git rev-parse --show-object-format >actual &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
git rev-parse --show-object-format=storage >actual &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
git rev-parse --show-object-format=input >actual &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
git rev-parse --show-object-format=output >actual &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
test_must_fail git rev-parse --show-object-format=squeamish-ossifrage 2>err &&
|
|
|
|
grep "unknown mode for --show-object-format: squeamish-ossifrage" err
|
|
|
|
'
|
|
|
|
|
2023-12-29 07:27:00 +00:00
|
|
|
test_expect_success 'rev-parse --show-ref-format' '
|
|
|
|
test_detect_ref_format >expect &&
|
|
|
|
git rev-parse --show-ref-format >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'rev-parse --show-ref-format with invalid storage' '
|
|
|
|
test_when_finished "rm -rf repo" &&
|
|
|
|
git init repo &&
|
|
|
|
(
|
|
|
|
cd repo &&
|
|
|
|
git config extensions.refstorage broken &&
|
|
|
|
test_must_fail git rev-parse --show-ref-format 2>err &&
|
|
|
|
grep "error: invalid value for ${SQ}extensions.refstorage${SQ}: ${SQ}broken${SQ}" err
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2019-11-19 08:05:43 +00:00
|
|
|
test_expect_success '--show-toplevel from subdir of working tree' '
|
|
|
|
pwd >expect &&
|
|
|
|
git -C sub/dir rev-parse --show-toplevel >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '--show-toplevel from inside .git' '
|
|
|
|
test_must_fail git -C .git rev-parse --show-toplevel
|
|
|
|
'
|
|
|
|
|
2017-03-08 23:07:42 +00:00
|
|
|
test_expect_success 'showing the superproject correctly' '
|
|
|
|
git rev-parse --show-superproject-working-tree >out &&
|
|
|
|
test_must_be_empty out &&
|
|
|
|
|
|
|
|
test_create_repo super &&
|
|
|
|
test_commit -C super test_commit &&
|
|
|
|
test_create_repo sub &&
|
|
|
|
test_commit -C sub test_commit &&
|
2022-07-29 19:16:10 +00:00
|
|
|
git -c protocol.file.allow=always \
|
|
|
|
-C super submodule add ../sub dir/sub &&
|
2017-03-08 23:07:42 +00:00
|
|
|
echo $(pwd)/super >expect &&
|
2018-09-27 18:10:54 +00:00
|
|
|
git -C super/dir/sub rev-parse --show-superproject-working-tree >out &&
|
|
|
|
test_cmp expect out &&
|
|
|
|
|
|
|
|
test_commit -C super submodule_add &&
|
|
|
|
git -C super checkout -b branch1 &&
|
|
|
|
git -C super/dir/sub checkout -b branch1 &&
|
|
|
|
test_commit -C super/dir/sub branch1_commit &&
|
|
|
|
git -C super add dir/sub &&
|
|
|
|
test_commit -C super branch1_commit &&
|
2020-11-18 23:44:21 +00:00
|
|
|
git -C super checkout -b branch2 main &&
|
|
|
|
git -C super/dir/sub checkout -b branch2 main &&
|
2018-09-27 18:10:54 +00:00
|
|
|
test_commit -C super/dir/sub branch2_commit &&
|
|
|
|
git -C super add dir/sub &&
|
|
|
|
test_commit -C super branch2_commit &&
|
|
|
|
test_must_fail git -C super merge branch1 &&
|
|
|
|
|
2017-03-08 23:07:42 +00:00
|
|
|
git -C super/dir/sub rev-parse --show-superproject-working-tree >out &&
|
|
|
|
test_cmp expect out
|
|
|
|
'
|
|
|
|
|
2021-02-10 21:55:43 +00:00
|
|
|
# at least one external project depends on this behavior:
|
|
|
|
test_expect_success 'rev-parse --since= unsqueezed ordering' '
|
|
|
|
x1=--since=1970-01-01T00:00:01Z &&
|
|
|
|
x2=--since=1970-01-01T00:00:02Z &&
|
|
|
|
x3=--since=1970-01-01T00:00:03Z &&
|
|
|
|
git rev-parse $x1 $x1 $x3 $x2 >actual &&
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
--max-age=1
|
|
|
|
--max-age=1
|
|
|
|
--max-age=3
|
|
|
|
--max-age=2
|
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
ref-cache.c: fix prefix matching in ref iteration
Update 'cache_ref_iterator_advance' to skip over refs that are not matched
by the given prefix.
Currently, a ref entry is considered "matched" if the entry name is fully
contained within the prefix:
* prefix: "refs/heads/v1"
* entry: "refs/heads/v1.0"
OR if the prefix is fully contained in the entry name:
* prefix: "refs/heads/v1.0"
* entry: "refs/heads/v1"
The first case is always correct, but the second is only correct if the ref
cache entry is a directory, for example:
* prefix: "refs/heads/example"
* entry: "refs/heads/"
Modify the logic in 'cache_ref_iterator_advance' to reflect these
expectations:
1. If 'overlaps_prefix' returns 'PREFIX_EXCLUDES_DIR', then the prefix and
ref cache entry do not overlap at all. Skip this entry.
2. If 'overlaps_prefix' returns 'PREFIX_WITHIN_DIR', then the prefix matches
inside this entry if it is a directory. Skip if the entry is not a
directory, otherwise iterate over it.
3. Otherwise, 'overlaps_prefix' returned 'PREFIX_CONTAINS_DIR', indicating
that the cache entry (directory or not) is fully contained by or equal to
the prefix. Iterate over this entry.
Note that condition 2 relies on the names of directory entries having the
appropriate trailing slash. The existing function documentation of
'create_dir_entry' explicitly calls out the trailing slash requirement, so
this is a safe assumption to make.
This bug generally doesn't have any user-facing impact, since it requires:
1. using a non-empty prefix without a trailing slash in an iteration like
'for_each_fullref_in',
2. the callback to said iteration not reapplying the original filter (as
for-each-ref does) to ensure unmatched refs are skipped, and
3. the repository having one or more refs that match part of, but not all
of, the prefix.
However, there are some niche scenarios that meet those criteria
(specifically, 'rev-parse --bisect' and '(log|show|shortlog) --bisect'). Add
tests covering those cases to demonstrate the fix in this patch.
Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-10-09 21:58:53 +00:00
|
|
|
test_expect_success 'rev-parse --bisect includes bad, excludes good' '
|
|
|
|
test_commit_bulk 6 &&
|
|
|
|
|
|
|
|
git update-ref refs/bisect/bad-1 HEAD~1 &&
|
|
|
|
git update-ref refs/bisect/b HEAD~2 &&
|
|
|
|
git update-ref refs/bisect/bad-3 HEAD~3 &&
|
|
|
|
git update-ref refs/bisect/good-3 HEAD~3 &&
|
|
|
|
git update-ref refs/bisect/bad-4 HEAD~4 &&
|
|
|
|
git update-ref refs/bisect/go HEAD~4 &&
|
|
|
|
|
|
|
|
# Note: refs/bisect/b and refs/bisect/go should be ignored because they
|
|
|
|
# do not match the refs/bisect/bad or refs/bisect/good prefixes.
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
refs/bisect/bad-1
|
|
|
|
refs/bisect/bad-3
|
|
|
|
refs/bisect/bad-4
|
|
|
|
^refs/bisect/good-3
|
|
|
|
EOF
|
|
|
|
|
|
|
|
git rev-parse --symbolic-full-name --bisect >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2007-06-06 07:01:21 +00:00
|
|
|
test_done
|