]> git.ipfire.org Git - thirdparty/git.git/commitdiff
last-modified: verify revision argument is a commit-ish
authorToon Claes <toon@iotcl.com>
Fri, 30 Jan 2026 14:26:38 +0000 (15:26 +0100)
committerJunio C Hamano <gitster@pobox.com>
Fri, 30 Jan 2026 16:57:01 +0000 (08:57 -0800)
Passing a non-committish revision to git-last-modified(1) triggers the
following BUG:

    git last-modified HEAD^{tree}
    BUG: builtin/last-modified.c:456: paths remaining beyond boundary in last-modified

Fix this error by ensuring that the given revision peels to a commit.

This change also adds a test to verify git-last-modified(1) can operate
on an annotated tag. For this an annotated tag is added that points to
the second commit. But this causes ambiguous results when calling
git-name-rev(1) with `--tags`, because now two tags point to the same
commit. To remove this ambiguity, pass `--exclude=<tag>` to
git-name-rev(1) to exclude the new annotated tag.

Reported-by: Gusted <gusted@codeberg.org>
Signed-off-by: Toon Claes <toon@iotcl.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/last-modified.c
t/t8020-last-modified.sh

index e02ec8428b1c365b55f4112bebc445a6d2fb35a6..d0944673f080f7237dce229a9d90651cc7764eee 100644 (file)
@@ -150,6 +150,11 @@ static int populate_paths_from_revs(struct last_modified *lm)
                        goto out;
                }
 
+               if (!repo_peel_to_type(lm->rev.repo, obj->path, 0, obj->item, OBJ_COMMIT)) {
+                       ret = error(_("revision argument '%s' is a %s, not a commit-ish"), obj->name, type_name(obj->item->type));
+                       goto out;
+               }
+
                diff_tree_oid(lm->rev.repo->hash_algo->empty_tree,
                              &obj->item->oid, "", &diffopt);
                diff_flush(&diffopt);
index d1aad1231938f6832378fdda9068c54063bb897e..ec5bdc6aa083a8d8b9f7cf6e4b2a54604596e898 100755 (executable)
@@ -8,6 +8,7 @@ test_expect_success 'setup' '
        test_commit 1 file &&
        mkdir a &&
        test_commit 2 a/file &&
+       git tag -mA t2 2 &&
        mkdir a/b &&
        test_commit 3 a/b/file
 '
@@ -30,7 +31,7 @@ check_last_modified() {
 
        cat >expect &&
        git ${indir:+-C "$indir"} last-modified "$@" >tmp.1 &&
-       git name-rev --annotate-stdin --name-only --tags \
+       git name-rev --annotate-stdin --name-only --tags --exclude=t2 \
                <tmp.1 >tmp.2 &&
        tr '\t' ' ' <tmp.2 >actual &&
        test_cmp expect actual
@@ -51,6 +52,13 @@ test_expect_success 'last-modified recursive' '
        EOF
 '
 
+test_expect_success 'last-modified on annotated tag' '
+       check_last_modified t2 <<-\EOF
+       2 a
+       1 file
+       EOF
+'
+
 test_expect_success 'last-modified recursive with show-trees' '
        check_last_modified -r -t <<-\EOF
        3 a/b
@@ -236,4 +244,9 @@ test_expect_success 'last-modified complains about unknown arguments' '
        test_grep "unknown last-modified argument: --foo" err
 '
 
+test_expect_success 'last-modified expects commit-ish' '
+       test_must_fail git last-modified HEAD^{tree} 2>err &&
+       test_grep "revision argument ${SQ}HEAD^{tree}${SQ} is a tree, not a commit-ish" err
+'
+
 test_done