mirror of
https://github.com/git/git.git
synced 2024-11-23 18:05:29 +08:00
a4324babe6
In 9830926c7d
(rev-list: add commit object support in `--missing`
option, 2023-10-27) we fixed the `--missing` option in `git rev-list`
so that it works with missing commits, not just blobs/trees.
Unfortunately, such a command was still failing with a "fatal: bad
object <oid>" if it was passed a missing commit, blob or tree as an
argument (before the rev walking even begins). This was fixed in a
recent commit.
That fix still doesn't work when an argument passed to the command is
an annotated tag pointing to a missing commit though. In that case
`git rev-list --missing=...` still errors out with a "fatal: bad
object <oid>" error where <oid> is the object ID of the missing
commit.
Let's fix this issue, and also, while at it, let's add tests not just
for annotated tags but also for regular tags and branches.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
150 lines
4.1 KiB
Bash
Executable File
150 lines
4.1 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='handling of missing objects in rev-list'
|
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
|
. ./test-lib.sh
|
|
|
|
# We setup the repository with two commits, this way HEAD is always
|
|
# available and we can hide commit 1.
|
|
test_expect_success 'create repository and alternate directory' '
|
|
test_commit 1 &&
|
|
test_commit 2 &&
|
|
test_commit 3 &&
|
|
git tag -m "tag message" annot_tag HEAD~1 &&
|
|
git tag regul_tag HEAD~1 &&
|
|
git branch a_branch HEAD~1
|
|
'
|
|
|
|
# We manually corrupt the repository, which means that the commit-graph may
|
|
# contain references to already-deleted objects. We thus need to enable
|
|
# commit-graph paranoia to not returned these deleted commits from the graph.
|
|
GIT_COMMIT_GRAPH_PARANOIA=true
|
|
export GIT_COMMIT_GRAPH_PARANOIA
|
|
|
|
for obj in "HEAD~1" "HEAD~1^{tree}" "HEAD:1.t"
|
|
do
|
|
test_expect_success "rev-list --missing=error fails with missing object $obj" '
|
|
oid="$(git rev-parse $obj)" &&
|
|
path=".git/objects/$(test_oid_to_path $oid)" &&
|
|
|
|
mv "$path" "$path.hidden" &&
|
|
test_when_finished "mv $path.hidden $path" &&
|
|
|
|
test_must_fail git rev-list --missing=error --objects \
|
|
--no-object-names HEAD
|
|
'
|
|
done
|
|
|
|
for obj in "HEAD~1" "HEAD~1^{tree}" "HEAD:1.t"
|
|
do
|
|
for action in "allow-any" "print"
|
|
do
|
|
test_expect_success "rev-list --missing=$action with missing $obj" '
|
|
oid="$(git rev-parse $obj)" &&
|
|
path=".git/objects/$(test_oid_to_path $oid)" &&
|
|
|
|
# Before the object is made missing, we use rev-list to
|
|
# get the expected oids.
|
|
git rev-list --objects --no-object-names \
|
|
HEAD ^$obj >expect.raw &&
|
|
|
|
# Blobs are shared by all commits, so even though a commit/tree
|
|
# might be skipped, its blob must be accounted for.
|
|
if test $obj != "HEAD:1.t"
|
|
then
|
|
echo $(git rev-parse HEAD:1.t) >>expect.raw &&
|
|
echo $(git rev-parse HEAD:2.t) >>expect.raw
|
|
fi &&
|
|
|
|
mv "$path" "$path.hidden" &&
|
|
test_when_finished "mv $path.hidden $path" &&
|
|
|
|
git rev-list --missing=$action --objects --no-object-names \
|
|
HEAD >actual.raw &&
|
|
|
|
# When the action is to print, we should also add the missing
|
|
# oid to the expect list.
|
|
case $action in
|
|
allow-any)
|
|
;;
|
|
print)
|
|
grep ?$oid actual.raw &&
|
|
echo ?$oid >>expect.raw
|
|
;;
|
|
esac &&
|
|
|
|
sort actual.raw >actual &&
|
|
sort expect.raw >expect &&
|
|
test_cmp expect actual
|
|
'
|
|
done
|
|
done
|
|
|
|
for missing_tip in "annot_tag" "regul_tag" "a_branch" "HEAD~1" "HEAD~1^{tree}" "HEAD:1.t"
|
|
do
|
|
# We want to check that things work when both
|
|
# - all the tips passed are missing (case existing_tip = ""), and
|
|
# - there is one missing tip and one existing tip (case existing_tip = "HEAD")
|
|
for existing_tip in "" "HEAD"
|
|
do
|
|
for action in "allow-any" "print"
|
|
do
|
|
test_expect_success "--missing=$action with tip '$missing_tip' missing and tip '$existing_tip'" '
|
|
# Before the object is made missing, we use rev-list to
|
|
# get the expected oids.
|
|
if test "$existing_tip" = "HEAD"
|
|
then
|
|
git rev-list --objects --no-object-names \
|
|
HEAD ^$missing_tip >expect.raw
|
|
else
|
|
>expect.raw
|
|
fi &&
|
|
|
|
# Blobs are shared by all commits, so even though a commit/tree
|
|
# might be skipped, its blob must be accounted for.
|
|
if test "$existing_tip" = "HEAD" && test $missing_tip != "HEAD:1.t"
|
|
then
|
|
echo $(git rev-parse HEAD:1.t) >>expect.raw &&
|
|
echo $(git rev-parse HEAD:2.t) >>expect.raw
|
|
fi &&
|
|
|
|
missing_oid="$(git rev-parse $missing_tip)" &&
|
|
|
|
if test "$missing_tip" = "annot_tag"
|
|
then
|
|
oid="$(git rev-parse $missing_tip^{commit})" &&
|
|
echo "$missing_oid" >>expect.raw
|
|
else
|
|
oid="$missing_oid"
|
|
fi &&
|
|
|
|
path=".git/objects/$(test_oid_to_path $oid)" &&
|
|
|
|
mv "$path" "$path.hidden" &&
|
|
test_when_finished "mv $path.hidden $path" &&
|
|
|
|
git rev-list --missing=$action --objects --no-object-names \
|
|
$missing_oid $existing_tip >actual.raw &&
|
|
|
|
# When the action is to print, we should also add the missing
|
|
# oid to the expect list.
|
|
case $action in
|
|
allow-any)
|
|
;;
|
|
print)
|
|
grep ?$oid actual.raw &&
|
|
echo ?$oid >>expect.raw
|
|
;;
|
|
esac &&
|
|
|
|
sort actual.raw >actual &&
|
|
sort expect.raw >expect &&
|
|
test_cmp expect actual
|
|
'
|
|
done
|
|
done
|
|
done
|
|
|
|
test_done
|