Subject: Re: t1450-fsck (sometimes/often) failes on Mac OS X

From: Torsten Bögershausen <[email-masked]>
Date: Tue, 02 Oct 2012 18:06:35 +0200

On 09/19/2012 08:30 PM, Junio C Hamano wrote:
> Torsten Bögershausen <[email-masked]> writes:
>
> "is a blob, not a commit" is likely to come from validating of the
> tag 66f6581d that presumably point at 63499e4; it reads the tag,
> learns the name of the object that is tagged and the type of it,
> remembers that the object pointed at (which it hasn't and is going
> to validate next) _must_ be a commit (because tag says so) and then
> realizes when it reads 63499e4 it is a blob and barfs.
>
> And that is what _should_ happen in that test.  It crafts a
> malformed tag that points at a blob and claims that it is a commit.
> The test makes sure fsck catches that, and it does.
>
> On the other hand, "is a commit, not a blob", unless you have a tag
> that directly points at a blob, is more likely to come from
> validating some tree object.  It reads the tree, learns the name of
> the object contained in the tree and infers the type of that object
> from the mode bits in the tree (100644 or 100755 would mean the
> object must be a blob), goes on to validate that object and realizes
> it is a commit and barfs.
>

The good news:
With help of Junio's comments I probably found the reason why the test 
behaves differently:

The objects are checked in a certain order, based on the inode number.

Which seems to be the same on most machines: when files are created
in a certain order, then the inode numbers are in the same order.

When the inode numbering changes for reasons known to the file system, 
the order changes and fsck takes a different code path.

To provoke the error, the following helped at my Linux box:

diff --git a/builtin/fsck.c b/builtin/fsck.c
index a710227..bba8082 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -373,7 +373,7 @@ static struct {

  static int ino_compare(const void *_a, const void *_b)
  {
-       const struct sha1_entry *a = _a, *b = _b;
+       const struct sha1_entry *a = _b, *b = _a;
         unsigned long ino1 = a->ino, ino2 = b->ino;
         return ino1 < ino2 ? -1 : ino1 > ino2 ? 1 : 0;
  }

The bad news: I haven't found the time to prepare a fix.

/Torsten