From: Torsten Bögershausen Date: Tue, 02 Oct 2012 16:06:35 GMT Subject: Re: t1450-fsck (sometimes/often) failes on Mac OS X Message-ID: <506B110B.2050802@web.de> In-Reply-To: <7va9wlhnl3.fsf@alter.siamese.dyndns.org> On 09/19/2012 08:30 PM, Junio C Hamano wrote: > Torsten Bögershausen 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