]> git.ipfire.org Git - thirdparty/git.git/commitdiff
revision: fix --missing=[print|allow*] for annotated tags
authorChristian Couder <christian.couder@gmail.com>
Wed, 28 Feb 2024 09:10:11 +0000 (10:10 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 28 Feb 2024 17:28:18 +0000 (09:28 -0800)
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>
revision.c
t/t6022-rev-list-missing.sh

index 80c349d3479b42a5bdc074cb05d667e0184ca5e1..6ebde81f76be4f4518bb27df060db678dc071003 100644 (file)
@@ -419,15 +419,21 @@ static struct commit *handle_commit(struct rev_info *revs,
         */
        while (object->type == OBJ_TAG) {
                struct tag *tag = (struct tag *) object;
+               struct object_id *oid;
                if (revs->tag_objects && !(flags & UNINTERESTING))
                        add_pending_object(revs, object, tag->tag);
-               object = parse_object(revs->repo, get_tagged_oid(tag));
+               oid = get_tagged_oid(tag);
+               object = parse_object(revs->repo, oid);
                if (!object) {
                        if (revs->ignore_missing_links || (flags & UNINTERESTING))
                                return NULL;
                        if (revs->exclude_promisor_objects &&
                            is_promisor_object(&tag->tagged->oid))
                                return NULL;
+                       if (revs->do_not_die_on_missing_objects && oid) {
+                               oidset_insert(&revs->missing_commits, oid);
+                               return NULL;
+                       }
                        die("bad object %s", oid_to_hex(&tag->tagged->oid));
                }
                object->flags |= flags;
index 78387eebb3fcb0e6fb896a7b61f638c56c157ee9..127180e1c9a246769fb5bb7ede57f814abb4fc79 100755 (executable)
@@ -10,7 +10,10 @@ TEST_PASSES_SANITIZE_LEAK=true
 test_expect_success 'create repository and alternate directory' '
        test_commit 1 &&
        test_commit 2 &&
-       test_commit 3
+       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
@@ -78,7 +81,7 @@ do
        done
 done
 
-for missing_tip in "HEAD~1" "HEAD~1^{tree}" "HEAD:1.t"
+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
@@ -88,9 +91,6 @@ do
                for action in "allow-any" "print"
                do
                        test_expect_success "--missing=$action with tip '$missing_tip' missing and tip '$existing_tip'" '
-                               oid="$(git rev-parse $missing_tip)" &&
-                               path=".git/objects/$(test_oid_to_path $oid)" &&
-
                                # Before the object is made missing, we use rev-list to
                                # get the expected oids.
                                if test "$existing_tip" = "HEAD"
@@ -109,11 +109,23 @@ do
                                        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 \
-                                    $oid $existing_tip >actual.raw &&
+                                    $missing_oid $existing_tip >actual.raw &&
 
                                # When the action is to print, we should also add the missing
                                # oid to the expect list.