fsck: report trees as dangling

After checking connectivity, fsck looks through the list of any objects we've seen mentioned, and reports unreachable and un-"used" ones as dangling. However, it skips any object which is not marked as "parsed", as that is an object that we _don't_ have (but that somebody mentioned). Since 6e454b9a3 (clear parsed flag when we free tree buffers, 2013-06-05), that flag can't be relied on, and the correct method is to check the HAS_OBJ flag. The cleanup in that commit missed this callsite, though. As a result, we would generally fail to report dangling trees. We never noticed because there were no tests in this area (for trees or otherwise). Let's add some. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Jan 16, 2017 at 16:25 UTC b4584e4f665f59f51572f479db6baf1a1cdbc03a
2 files changed +28 -1
builtin/fsck.c
+1 -1
@@ -225,7 +225,7 @@ static void check_unreachable_object(struct object *obj)
225 * to complain about it being unreachable (since it does
226 * not exist).
227 */
228 - if (!obj->parsed)
228 + if (!(obj->flags & HAS_OBJ))
229 return;
230
231 /*
t/t1450-fsck.sh
+27
@@ -559,4 +559,31 @@ test_expect_success 'fsck --name-objects' '
559 )
560 '
561
562 +# for each of type, we have one version which is referenced by another object
563 +# (and so while unreachable, not dangling), and another variant which really is
564 +# dangling.
565 +test_expect_success 'fsck notices dangling objects' '
566 + git init dangling &&
567 + (
568 + cd dangling &&
569 + blob=$(echo not-dangling | git hash-object -w --stdin) &&
570 + dblob=$(echo dangling | git hash-object -w --stdin) &&
571 + tree=$(printf "100644 blob %s\t%s\n" $blob one | git mktree) &&
572 + dtree=$(printf "100644 blob %s\t%s\n" $blob two | git mktree) &&
573 + commit=$(git commit-tree $tree) &&
574 + dcommit=$(git commit-tree -p $commit $tree) &&
575 +
576 + cat >expect <<-EOF &&
577 + dangling blob $dblob
578 + dangling commit $dcommit
579 + dangling tree $dtree
580 + EOF
581 +
582 + git fsck >actual &&
583 + # the output order is non-deterministic, as it comes from a hash
584 + sort <actual >actual.sorted &&
585 + test_cmp expect actual.sorted
586 + )
587 +'
588 +
589 test_done