2008-05-11 18:27:10 +02:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (c) 2008 Christian Couder
|
|
|
|
#
|
|
|
|
test_description='test git rev-parse --verify'
|
|
|
|
|
|
|
|
exec </dev/null
|
|
|
|
|
2020-11-19 00:44:21 +01: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-19 00:44:19 +01:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
2008-05-11 18:27:10 +02:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
add_line_into_file()
|
|
|
|
{
|
|
|
|
_line=$1
|
|
|
|
_file=$2
|
|
|
|
|
|
|
|
if [ -f "$_file" ]; then
|
|
|
|
echo "$_line" >> $_file || return $?
|
|
|
|
MSG="Add <$_line> into <$_file>."
|
|
|
|
else
|
|
|
|
echo "$_line" > $_file || return $?
|
|
|
|
git add $_file || return $?
|
|
|
|
MSG="Create file <$_file> with <$_line> inside."
|
|
|
|
fi
|
|
|
|
|
|
|
|
test_tick
|
2008-09-03 10:59:27 +02:00
|
|
|
git commit --quiet -m "$MSG" $_file
|
2008-05-11 18:27:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
HASH1=
|
|
|
|
HASH2=
|
|
|
|
HASH3=
|
|
|
|
HASH4=
|
|
|
|
|
|
|
|
test_expect_success 'set up basic repo with 1 file (hello) and 4 commits' '
|
|
|
|
add_line_into_file "1: Hello World" hello &&
|
|
|
|
HASH1=$(git rev-parse --verify HEAD) &&
|
|
|
|
add_line_into_file "2: A new day for git" hello &&
|
|
|
|
HASH2=$(git rev-parse --verify HEAD) &&
|
|
|
|
add_line_into_file "3: Another new day for git" hello &&
|
|
|
|
HASH3=$(git rev-parse --verify HEAD) &&
|
|
|
|
add_line_into_file "4: Ciao for now" hello &&
|
|
|
|
HASH4=$(git rev-parse --verify HEAD)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'works with one good rev' '
|
|
|
|
rev_hash1=$(git rev-parse --verify $HASH1) &&
|
|
|
|
test "$rev_hash1" = "$HASH1" &&
|
|
|
|
rev_hash2=$(git rev-parse --verify $HASH2) &&
|
|
|
|
test "$rev_hash2" = "$HASH2" &&
|
|
|
|
rev_hash3=$(git rev-parse --verify $HASH3) &&
|
|
|
|
test "$rev_hash3" = "$HASH3" &&
|
|
|
|
rev_hash4=$(git rev-parse --verify $HASH4) &&
|
|
|
|
test "$rev_hash4" = "$HASH4" &&
|
2020-11-19 00:44:21 +01:00
|
|
|
rev_main=$(git rev-parse --verify main) &&
|
|
|
|
test "$rev_main" = "$HASH4" &&
|
2008-05-11 18:27:10 +02:00
|
|
|
rev_head=$(git rev-parse --verify HEAD) &&
|
|
|
|
test "$rev_head" = "$HASH4"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'fails with any bad rev or many good revs' '
|
|
|
|
test_must_fail git rev-parse --verify 2>error &&
|
|
|
|
grep "single revision" error &&
|
|
|
|
test_must_fail git rev-parse --verify foo 2>error &&
|
|
|
|
grep "single revision" error &&
|
|
|
|
test_must_fail git rev-parse --verify HEAD bar 2>error &&
|
|
|
|
grep "single revision" error &&
|
|
|
|
test_must_fail git rev-parse --verify baz HEAD 2>error &&
|
|
|
|
grep "single revision" error &&
|
|
|
|
test_must_fail git rev-parse --verify $HASH2 HEAD 2>error &&
|
|
|
|
grep "single revision" error
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'fails silently when using -q' '
|
|
|
|
test_must_fail git rev-parse --verify --quiet 2>error &&
|
2014-09-16 05:24:08 +02:00
|
|
|
test_must_be_empty error &&
|
2008-05-11 18:27:10 +02:00
|
|
|
test_must_fail git rev-parse -q --verify foo 2>error &&
|
2014-09-16 05:24:08 +02:00
|
|
|
test_must_be_empty error &&
|
2008-05-11 18:27:10 +02:00
|
|
|
test_must_fail git rev-parse --verify -q HEAD bar 2>error &&
|
2014-09-16 05:24:08 +02:00
|
|
|
test_must_be_empty error &&
|
2008-05-11 18:27:10 +02:00
|
|
|
test_must_fail git rev-parse --quiet --verify baz HEAD 2>error &&
|
2014-09-16 05:24:08 +02:00
|
|
|
test_must_be_empty error &&
|
2008-05-11 18:27:10 +02:00
|
|
|
test_must_fail git rev-parse -q --verify $HASH2 HEAD 2>error &&
|
2014-09-16 05:24:08 +02:00
|
|
|
test_must_be_empty error
|
2008-05-11 18:27:10 +02:00
|
|
|
'
|
|
|
|
|
2014-09-19 05:45:37 +02:00
|
|
|
test_expect_success 'fails silently when using -q with deleted reflogs' '
|
|
|
|
ref=$(git rev-parse HEAD) &&
|
2015-07-28 00:57:08 +02:00
|
|
|
git update-ref --create-reflog -m "message for refs/test" refs/test "$ref" &&
|
2021-01-07 11:36:59 +01:00
|
|
|
git reflog delete --updateref --rewrite refs/test@{1} &&
|
|
|
|
test_must_fail git rev-parse -q --verify refs/test@{1} >error 2>&1 &&
|
2014-09-19 05:45:37 +02:00
|
|
|
test_must_be_empty error
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'fails silently when using -q with not enough reflogs' '
|
|
|
|
ref=$(git rev-parse HEAD) &&
|
2015-07-28 00:57:08 +02:00
|
|
|
git update-ref --create-reflog -m "message for refs/test2" refs/test2 "$ref" &&
|
2014-09-19 05:45:37 +02:00
|
|
|
test_must_fail git rev-parse -q --verify refs/test2@{999} >error 2>&1 &&
|
|
|
|
test_must_be_empty error
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'succeeds silently with -q and reflogs that do not go far back enough in time' '
|
|
|
|
ref=$(git rev-parse HEAD) &&
|
2015-07-28 00:57:08 +02:00
|
|
|
git update-ref --create-reflog -m "message for refs/test3" refs/test3 "$ref" &&
|
2014-09-19 05:45:37 +02:00
|
|
|
git rev-parse -q --verify refs/test3@{1.year.ago} >actual 2>error &&
|
|
|
|
test_must_be_empty error &&
|
|
|
|
echo "$ref" >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2008-05-11 18:28:25 +02:00
|
|
|
test_expect_success 'no stdout output on error' '
|
2008-05-11 18:27:10 +02:00
|
|
|
test -z "$(git rev-parse --verify)" &&
|
|
|
|
test -z "$(git rev-parse --verify foo)" &&
|
2008-05-11 18:28:25 +02:00
|
|
|
test -z "$(git rev-parse --verify baz HEAD)" &&
|
|
|
|
test -z "$(git rev-parse --verify HEAD bar)" &&
|
2008-05-11 18:27:10 +02:00
|
|
|
test -z "$(git rev-parse --verify $HASH2 HEAD)"
|
|
|
|
'
|
|
|
|
|
2008-05-11 18:27:36 +02:00
|
|
|
test_expect_success 'use --default' '
|
2020-11-19 00:44:21 +01:00
|
|
|
git rev-parse --verify --default main &&
|
|
|
|
git rev-parse --verify --default main HEAD &&
|
|
|
|
git rev-parse --default main --verify &&
|
|
|
|
git rev-parse --default main --verify HEAD &&
|
|
|
|
git rev-parse --verify HEAD --default main &&
|
|
|
|
test_must_fail git rev-parse --verify foo --default main &&
|
2008-05-11 18:27:10 +02:00
|
|
|
test_must_fail git rev-parse --default HEAD --verify bar &&
|
2008-05-11 18:27:36 +02:00
|
|
|
test_must_fail git rev-parse --verify --default HEAD baz &&
|
|
|
|
test_must_fail git rev-parse --default foo --verify &&
|
|
|
|
test_must_fail git rev-parse --verify --default bar
|
2008-05-11 18:27:10 +02:00
|
|
|
'
|
|
|
|
|
2020-11-19 00:44:21 +01:00
|
|
|
test_expect_success 'main@{n} for various n' '
|
2010-08-24 06:52:44 +02:00
|
|
|
N=$(git reflog | wc -l) &&
|
2010-09-21 19:45:09 +02:00
|
|
|
Nm1=$(($N-1)) &&
|
|
|
|
Np1=$(($N+1)) &&
|
2020-11-19 00:44:21 +01:00
|
|
|
git rev-parse --verify main@{0} &&
|
|
|
|
git rev-parse --verify main@{1} &&
|
|
|
|
git rev-parse --verify main@{$Nm1} &&
|
|
|
|
test_must_fail git rev-parse --verify main@{$N} &&
|
|
|
|
test_must_fail git rev-parse --verify main@{$Np1}
|
2010-08-24 06:52:44 +02:00
|
|
|
'
|
|
|
|
|
files_read_raw_ref: avoid infinite loop on broken symlinks
Our ref resolution first runs lstat() on any path we try to
look up, because we want to treat symlinks specially (by
resolving them manually and considering them symrefs). But
if the results of `readlink` do _not_ look like a ref, we
fall through to treating it like a normal file, and just
read the contents of the linked path.
Since fcb7c76 (resolve_ref_unsafe(): close race condition
reading loose refs, 2013-06-19), that "normal file" code
path will stat() the file and if we see ENOENT, will jump
back to the lstat(), thinking we've seen inconsistent
results between the two calls. But for a symbolic ref, this
isn't a race: the lstat() found the symlink, and the stat()
is looking at the path it points to. We end up in an
infinite loop calling lstat() and stat().
We can fix this by avoiding the retry-on-inconsistent jump
when we know that we found a symlink. While we're at it,
let's add a comment explaining why the symlink case gets to
this code in the first place; without that, it is not
obvious that the correct solution isn't to avoid the stat()
code path entirely.
Signed-off-by: Jeff King <peff@peff.net>
Reviewed-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-10-06 21:41:08 +02:00
|
|
|
test_expect_success SYMLINKS 'ref resolution not confused by broken symlinks' '
|
|
|
|
ln -s does-not-exist .git/refs/heads/broken &&
|
|
|
|
test_must_fail git rev-parse --verify broken
|
|
|
|
'
|
|
|
|
|
rev-parse: handle --end-of-options
We taught rev-list a new way to separate options from revisions in
19e8789b23 (revision: allow --end-of-options to end option parsing,
2019-08-06), but rev-parse uses its own parser. It should know about
--end-of-options not only for consistency, but because it may be
presented with similarly ambiguous cases. E.g., if a caller does:
git rev-parse "$rev" -- "$path"
to parse an untrusted input, then it will get confused if $rev contains
an option-like string like "--local-env-vars". Or even "--not-real",
which we'd keep as an option to pass along to rev-list.
Or even more importantly:
git rev-parse --verify "$rev"
can be confused by options, even though its purpose is safely parsing
untrusted input. On the plus side, it will always fail the --verify
part, as it will not have parsed a revision, so the caller will
generally "fail closed" rather than continue to use the untrusted
string. But it will still trigger whatever option was in "$rev"; this
should be mostly harmless, since rev-parse options are all read-only,
but I didn't carefully audit all paths.
This patch lets callers write:
git rev-parse --end-of-options "$rev" -- "$path"
and:
git rev-parse --verify --end-of-options "$rev"
which will both treat "$rev" always as a revision parameter. The latter
is a bit clunky. It would be nicer if we had defined "--verify" to
require that its next argument be the revision. But we have not
historically done so, and:
git rev-parse --verify -q "$rev"
does currently work. I added a test here to confirm that we didn't break
that.
A few implementation notes:
- We don't document --end-of-options explicitly in commands, but rather
in gitcli(7). So I didn't give it its own section in git-rev-parse(1).
But I did call it out specifically in the --verify section, and
include it in the examples, which should show best practices.
- We don't have to re-indent the main option-parsing block, because we
can combine our "did we see end of options" check with "does it start
with a dash". The exception is the pre-setup options, which need
their own block.
- We do however have to pull the "--" parsing out of the "does it start
with dash" block, because we want to parse it even if we've seen
--end-of-options.
- We'll leave "--end-of-options" in the output. This is probably not
technically necessary, as a careful caller will do:
git rev-parse --end-of-options $revs -- $paths
and anything in $revs will be resolved to an object id. However, it
does help a slightly less careful caller like:
git rev-parse --end-of-options $revs_or_paths
where a path "--foo" will remain in the output as long as it also
exists on disk. In that case, it's helpful to retain --end-of-options
to get passed along to rev-list, s it would otherwise see just
"--foo".
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-10 22:40:19 +01:00
|
|
|
test_expect_success 'options can appear after --verify' '
|
|
|
|
git rev-parse --verify HEAD >expect &&
|
|
|
|
git rev-parse --verify -q HEAD >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'verify respects --end-of-options' '
|
|
|
|
git update-ref refs/heads/-tricky HEAD &&
|
|
|
|
git rev-parse --verify HEAD >expect &&
|
|
|
|
git rev-parse --verify --end-of-options -tricky >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2008-05-11 18:27:10 +02:00
|
|
|
test_done
|