Add a test for the mode being passed to ent_compare(). That code dates back to 83f50539a9 (git-mktree: reverse of git-ls-tree., 2006-02-20) and there's never been a test for that particular edge case. Now we have one. I don't see how anything could run into this in practice. In order for that mode sorting to matter as a tiebreaker we need to have a duplicate entry in the tree, i.e. two "foo" entries, one a blob and one a tree. This asserts that if that happens we'll sort on the modes we encounter in such an invalid entry, i.e. we expect the tree entry before the blob. As shown here we'd need to disable the fsck.duplicateEntries error to get to the point of running "mktree", so I doubt anyone's pushing this sort of data around. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> --- t/t1450-fsck.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 5071ac63a5b..46125190b45 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -318,6 +318,50 @@ test_expect_success 'tree entry with type mismatch' ' test_i18ngrep ! "dangling blob" out ' +test_expect_success 'tree entry with duplicate type mismatching objects' ' + test_create_repo duplicate-entry && + ( + cd duplicate-entry && + blob="$(printf "foo" | git hash-object -w --stdin)" && + tree="$(printf "100644 blob $blob\tfoo" | git mktree)" && + commit="$(git commit-tree $tree -m "first commit")" && + git cat-file commit $commit >good-commit && + + # First bad commit, wrong type, but in the right order + printf "40000 A\0$(echo $tree | hex2oct)" >broken-tree-A && + printf "100644 A\0$(echo $blob | hex2oct)" >broken-tree-B && + cat broken-tree-A broken-tree-B >broken-tree.1 && + broken_tree1="$(git hash-object -w --literally -t tree broken-tree.1)" && + bad_commit1="$(git commit-tree $broken_tree1 -m "bad commit 1")" && + git cat-file commit $bad_commit1 >bad-commit.1 && + git update-ref refs/heads/broken-commit-1 $bad_commit1 && + + test_must_fail git fsck && + git -c fsck.duplicateEntries=warn fsck 2>err && + grep " in tree .*$broken_tree1: duplicateEntries" err && + + # Second bad commits, wrong types and order + cat broken-tree-B broken-tree-A >broken-tree.2 && + broken_tree2="$(git hash-object -w --literally -t tree broken-tree.2)" && + bad_commit2="$(git commit-tree $broken_tree2 -m "bad commit 2")" && + git cat-file commit $bad_commit2 >bad-commit.2 && + git update-ref refs/heads/broken-commit-2 $bad_commit2 && + + test_must_fail git fsck && + git -c fsck.duplicateEntries=warn fsck 2>err && + grep " in tree .*$broken_tree2: duplicateEntries" err && + + # git mktree should "fix" the order of this already broken data + git ls-tree broken-commit-1 >broken-tree-1-ls && + git ls-tree broken-commit-2 >broken-tree-2-ls && + ! test_cmp broken-tree-1-ls broken-tree-2-ls && + + git mktree <broken-tree-1-ls >broken-mktree-1 && + git mktree <broken-tree-2-ls >broken-mktree-2 && + test_cmp broken-mktree-1 broken-mktree-2 + ) +' + test_expect_success 'tag pointing to nonexistent' ' badoid=$(test_oid deadbeef) && cat >invalid-tag <<-EOF && -- 2.31.1.474.g72d45d12706