2010-09-19 23:24:29 +00:00
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
test_description='miscellaneous rev-list tests'
|
|
|
|
|
2020-11-18 23:44:36 +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
|
|
|
|
|
2024-06-11 09:20:24 +00:00
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
2010-09-19 23:24:29 +00:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success setup '
|
|
|
|
echo content1 >wanted_file &&
|
|
|
|
echo content2 >unwanted_file &&
|
|
|
|
git add wanted_file unwanted_file &&
|
t6000: use test_tick consistently
The first two commits created in t6000 are done without test_tick,
meaning they use the current system clock. After that, we create one
with test_tick, which means it uses a deterministic time in the past.
The result of the "symleft flag bit is propagated down from tag" test
relies on the output order of commits from git-log, which in turn
depends on these timestamps. So this test is technically dependent on
the system clock time, though in practice it would only matter if your
system clock was set before test_tick's default time (which is in 2005).
However, let's use test_tick consistently for those early commits (and
update the expected output to match). This makes the test deterministic,
which is in turn easier to reason about and debug.
Note that there's also a fourth commit here, and it does not use
test_tick. It does have a deterministic timestamp because of the prior
use of test_tick in the script, but it will always be the same time as
the third commit. Let's use test_tick here, too, for consistency. The
matching timestamps between the third and fourth commit are not an
important part of the test.
We could also use test_commit in all of these cases, as it runs
test_tick under the hood. But it would be awkward to do so, as these
tests diverge from the usual test_commit patterns (e.g., by creating
multiple files in a single commit).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-07-07 21:41:51 +00:00
|
|
|
test_tick &&
|
2010-09-19 23:24:29 +00:00
|
|
|
git commit -m one
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'rev-list --objects heeds pathspecs' '
|
|
|
|
git rev-list --objects HEAD -- wanted_file >output &&
|
|
|
|
grep wanted_file output &&
|
|
|
|
! grep unwanted_file output
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'rev-list --objects with pathspecs and deeper paths' '
|
|
|
|
mkdir foo &&
|
|
|
|
>foo/file &&
|
|
|
|
git add foo/file &&
|
t6000: use test_tick consistently
The first two commits created in t6000 are done without test_tick,
meaning they use the current system clock. After that, we create one
with test_tick, which means it uses a deterministic time in the past.
The result of the "symleft flag bit is propagated down from tag" test
relies on the output order of commits from git-log, which in turn
depends on these timestamps. So this test is technically dependent on
the system clock time, though in practice it would only matter if your
system clock was set before test_tick's default time (which is in 2005).
However, let's use test_tick consistently for those early commits (and
update the expected output to match). This makes the test deterministic,
which is in turn easier to reason about and debug.
Note that there's also a fourth commit here, and it does not use
test_tick. It does have a deterministic timestamp because of the prior
use of test_tick in the script, but it will always be the same time as
the third commit. Let's use test_tick here, too, for consistency. The
matching timestamps between the third and fourth commit are not an
important part of the test.
We could also use test_commit in all of these cases, as it runs
test_tick under the hood. But it would be awkward to do so, as these
tests diverge from the usual test_commit patterns (e.g., by creating
multiple files in a single commit).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-07-07 21:41:51 +00:00
|
|
|
test_tick &&
|
2010-09-19 23:24:29 +00:00
|
|
|
git commit -m two &&
|
|
|
|
|
|
|
|
git rev-list --objects HEAD -- foo >output &&
|
|
|
|
grep foo/file output &&
|
|
|
|
|
|
|
|
git rev-list --objects HEAD -- foo/file >output &&
|
|
|
|
grep foo/file output &&
|
|
|
|
! grep unwanted_file output
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'rev-list --objects with pathspecs and copied files' '
|
|
|
|
git checkout --orphan junio-testcase &&
|
|
|
|
git rm -rf . &&
|
|
|
|
|
|
|
|
mkdir two &&
|
|
|
|
echo frotz >one &&
|
|
|
|
cp one two/three &&
|
|
|
|
git add one two/three &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m that &&
|
|
|
|
|
2015-03-20 10:07:15 +00:00
|
|
|
ONE=$(git rev-parse HEAD:one) &&
|
2010-09-19 23:24:29 +00:00
|
|
|
git rev-list --objects HEAD two >output &&
|
|
|
|
grep "$ONE two/three" output &&
|
|
|
|
! grep one output
|
|
|
|
'
|
|
|
|
|
2019-06-19 20:56:56 +00:00
|
|
|
test_expect_success 'rev-list --objects --no-object-names has no space/names' '
|
|
|
|
git rev-list --objects --no-object-names HEAD >output &&
|
|
|
|
! grep wanted_file output &&
|
|
|
|
! grep unwanted_file output &&
|
|
|
|
! grep " " output
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'rev-list --objects --no-object-names works with cat-file' '
|
|
|
|
git rev-list --objects --no-object-names --all >list-output &&
|
|
|
|
git cat-file --batch-check <list-output >cat-output &&
|
|
|
|
! grep missing cat-output
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '--no-object-names and --object-names are last-one-wins' '
|
|
|
|
git rev-list --objects --no-object-names --object-names --all >output &&
|
|
|
|
grep wanted_file output &&
|
|
|
|
git rev-list --objects --object-names --no-object-names --all >output &&
|
|
|
|
! grep wanted_file output
|
|
|
|
'
|
|
|
|
|
2013-09-19 21:20:34 +00:00
|
|
|
test_expect_success 'rev-list A..B and rev-list ^A B are the same' '
|
t6000: use test_tick consistently
The first two commits created in t6000 are done without test_tick,
meaning they use the current system clock. After that, we create one
with test_tick, which means it uses a deterministic time in the past.
The result of the "symleft flag bit is propagated down from tag" test
relies on the output order of commits from git-log, which in turn
depends on these timestamps. So this test is technically dependent on
the system clock time, though in practice it would only matter if your
system clock was set before test_tick's default time (which is in 2005).
However, let's use test_tick consistently for those early commits (and
update the expected output to match). This makes the test deterministic,
which is in turn easier to reason about and debug.
Note that there's also a fourth commit here, and it does not use
test_tick. It does have a deterministic timestamp because of the prior
use of test_tick in the script, but it will always be the same time as
the third commit. Let's use test_tick here, too, for consistency. The
matching timestamps between the third and fourth commit are not an
important part of the test.
We could also use test_commit in all of these cases, as it runs
test_tick under the hood. But it would be awkward to do so, as these
tests diverge from the usual test_commit patterns (e.g., by creating
multiple files in a single commit).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-07-07 21:41:51 +00:00
|
|
|
test_tick &&
|
2013-09-19 21:20:34 +00:00
|
|
|
git commit --allow-empty -m another &&
|
|
|
|
git tag -a -m "annotated" v1.0 &&
|
|
|
|
git rev-list --objects ^v1.0^ v1.0 >expect &&
|
|
|
|
git rev-list --objects v1.0^..v1.0 >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2014-01-15 23:38:01 +00:00
|
|
|
test_expect_success 'propagate uninteresting flag down correctly' '
|
|
|
|
git rev-list --objects ^HEAD^{tree} HEAD^{tree} >actual &&
|
2018-07-27 17:48:11 +00:00
|
|
|
test_must_be_empty actual
|
2014-01-15 23:38:01 +00:00
|
|
|
'
|
|
|
|
|
2014-01-15 20:26:13 +00:00
|
|
|
test_expect_success 'symleft flag bit is propagated down from tag' '
|
2020-11-18 23:44:36 +00:00
|
|
|
git log --format="%m %s" --left-right v1.0...main >actual &&
|
2014-01-15 20:26:13 +00:00
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
< another
|
|
|
|
< that
|
t6000: use test_tick consistently
The first two commits created in t6000 are done without test_tick,
meaning they use the current system clock. After that, we create one
with test_tick, which means it uses a deterministic time in the past.
The result of the "symleft flag bit is propagated down from tag" test
relies on the output order of commits from git-log, which in turn
depends on these timestamps. So this test is technically dependent on
the system clock time, though in practice it would only matter if your
system clock was set before test_tick's default time (which is in 2005).
However, let's use test_tick consistently for those early commits (and
update the expected output to match). This makes the test deterministic,
which is in turn easier to reason about and debug.
Note that there's also a fourth commit here, and it does not use
test_tick. It does have a deterministic timestamp because of the prior
use of test_tick in the script, but it will always be the same time as
the third commit. Let's use test_tick here, too, for consistency. The
matching timestamps between the third and fourth commit are not an
important part of the test.
We could also use test_commit in all of these cases, as it runs
test_tick under the hood. But it would be awkward to do so, as these
tests diverge from the usual test_commit patterns (e.g., by creating
multiple files in a single commit).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-07-07 21:41:51 +00:00
|
|
|
> two
|
|
|
|
> one
|
2014-01-15 20:26:13 +00:00
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2014-10-17 00:44:23 +00:00
|
|
|
test_expect_success 'rev-list can show index objects' '
|
|
|
|
# Of the blobs and trees in the index, note:
|
|
|
|
#
|
|
|
|
# - we do not show two/three, because it is the
|
|
|
|
# same blob as "one", and we show objects only once
|
|
|
|
#
|
|
|
|
# - we do show the tree "two", because it has a valid cache tree
|
|
|
|
# from the last commit
|
|
|
|
#
|
|
|
|
# - we do not show the root tree; since we updated the index, it
|
|
|
|
# does not have a valid cache tree
|
|
|
|
#
|
|
|
|
echo only-in-index >only-in-index &&
|
2018-11-02 05:22:59 +00:00
|
|
|
test_when_finished "git reset --hard" &&
|
2020-02-07 00:52:52 +00:00
|
|
|
rev1=$(git rev-parse HEAD:one) &&
|
|
|
|
rev2=$(git rev-parse HEAD:two) &&
|
|
|
|
revi=$(git hash-object only-in-index) &&
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
$rev1 one
|
|
|
|
$revi only-in-index
|
|
|
|
$rev2 two
|
|
|
|
EOF
|
2014-10-17 00:44:23 +00:00
|
|
|
git add only-in-index &&
|
|
|
|
git rev-list --objects --indexed-objects >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2018-11-02 05:22:59 +00:00
|
|
|
test_expect_success 'rev-list can negate index objects' '
|
|
|
|
git rev-parse HEAD >expect &&
|
|
|
|
git rev-list -1 --objects HEAD --not --indexed-objects >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2020-08-07 21:58:35 +00:00
|
|
|
test_expect_success '--bisect and --first-parent can be combined' '
|
|
|
|
git rev-list --bisect --first-parent HEAD
|
2015-03-19 22:14:08 +00:00
|
|
|
'
|
|
|
|
|
2016-10-20 20:41:00 +00:00
|
|
|
test_expect_success '--header shows a NUL after each commit' '
|
|
|
|
# We know that there is no Q in the true payload; names and
|
|
|
|
# addresses of the authors and the committers do not have
|
|
|
|
# any, and object names or header names do not, either.
|
|
|
|
git rev-list --header --max-count=2 HEAD |
|
|
|
|
nul_to_q |
|
|
|
|
grep "^Q" >actual &&
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
Q$(git rev-parse HEAD~1)
|
|
|
|
Q
|
|
|
|
EOF
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
revision: allow --end-of-options to end option parsing
There's currently no robust way to tell Git that a particular option is
meant to be a revision, and not an option. So if you have a branch
"refs/heads/--foo", you cannot just say:
git rev-list --foo
You can say:
git rev-list refs/heads/--foo
But that breaks down if you don't know the refname, and in particular if
you're a script passing along a value from elsewhere. In most programs,
you can use "--" to end option parsing, like this:
some-prog -- "$revision"
But that doesn't work for the revision parser, because "--" is already
meaningful there: it separates revisions from pathspecs. So we need some
other marker to separate options from revisions.
This patch introduces "--end-of-options", which serves that purpose:
git rev-list --oneline --end-of-options "$revision"
will work regardless of what's in "$revision" (well, if you say "--" it
may fail, but it won't do something dangerous, like triggering an
unexpected option).
The name is verbose, but that's probably a good thing; this is meant to
be used for scripted invocations where readability is more important
than terseness.
One alternative would be to introduce an explicit option to mark a
revision, like:
git rev-list --oneline --revision="$revision"
That's slightly _more_ informative than this commit (because it makes
even something silly like "--" unambiguous). But the pattern of using a
separator like "--" is well established in git and in other commands,
and it makes some scripting tasks simpler like:
git rev-list --end-of-options "$@"
There's no documentation in this patch, because it will make sense to
describe the feature once it is available everywhere (and support will
be added in further patches).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-06 14:39:58 +00:00
|
|
|
test_expect_success 'rev-list --end-of-options' '
|
|
|
|
git update-ref refs/heads/--output=yikes HEAD &&
|
|
|
|
git rev-list --end-of-options --output=yikes >actual &&
|
|
|
|
test_path_is_missing yikes &&
|
|
|
|
git rev-list HEAD >expect &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2020-02-14 18:22:20 +00:00
|
|
|
test_expect_success 'rev-list --count' '
|
|
|
|
count=$(git rev-list --count HEAD) &&
|
|
|
|
git rev-list HEAD >actual &&
|
|
|
|
test_line_count = $count actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'rev-list --count --objects' '
|
|
|
|
count=$(git rev-list --count --objects HEAD) &&
|
|
|
|
git rev-list --objects HEAD >actual &&
|
|
|
|
test_line_count = $count actual
|
|
|
|
'
|
|
|
|
|
list-objects: drop --unpacked non-commit objects from results
In git-rev-list(1), we describe the `--unpacked` option as:
Only useful with `--objects`; print the object IDs that are not in
packs.
This is true of commits, which we discard via get_commit_action(), but
not of the objects they reach. So if we ask for an --objects traversal
with --unpacked, we may get arbitrarily many objects which are indeed
packed.
I am nearly certain this behavior dates back to the introduction of
`--unpacked` via 12d2a18780 ("git rev-list --unpacked" shows only
unpacked commits, 2005-07-03), but I couldn't get that revision of Git
to compile for me. At least as early as v2.0.0 this has been subtly
broken:
$ git.compile --version
git version 2.0.0
$ git.compile rev-list --objects --all --unpacked
72791fe96c93f9ec5c311b8bc966ab349b3b5bbe
05713d991c18bbeef7e154f99660005311b5004d v1.0
153ed8b7719c6f5a68ce7ffc43133e95a6ac0fdb
8e4020bb5a8d8c873b25de15933e75cc0fc275df one
9200b628cf9dc883a85a7abc8d6e6730baee589c two
3e6b46e1b7e3b91acce99f6a823104c28aae0b58 unpacked.t
There, only the first, third, and sixth entries are loose, with the
remaining set of objects belonging to at least one pack.
The implications for this are relatively benign: bare 'git repack'
invocations which invoke pack-objects with --unpacked are impacted, and
at worst we'll store a few extra objects that should have been excluded.
Arguably changing this behavior is a backwards-incompatible change,
since it alters the set of objects emitted from rev-list queries with
`--objects` and `--unpacked`. But I argue that this change is still
sensible, since the existing implementation deviates from
clearly-written documentation.
The fix here is straightforward: avoid showing any non-commit objects
which are contained in packs by discarding them within list-objects.c,
before they are shown to the user. Note that similar treatment for
`list-objects.c::show_commit()` is not needed, since that case is
already handled by `revision.c::get_commit_action()`.
Co-authored-by: Jeff King <peff@peff.net>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-11-06 22:56:30 +00:00
|
|
|
test_expect_success 'rev-list --unpacked' '
|
|
|
|
git repack -ad &&
|
|
|
|
test_commit unpacked &&
|
|
|
|
|
|
|
|
git rev-list --objects --no-object-names unpacked^.. >expect.raw &&
|
|
|
|
sort expect.raw >expect &&
|
|
|
|
|
|
|
|
git rev-list --all --objects --unpacked --no-object-names >actual.raw &&
|
|
|
|
sort actual.raw >actual &&
|
|
|
|
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2010-09-19 23:24:29 +00:00
|
|
|
test_done
|