fsck: handle promisor objects in .gitmodules check
authorJeff King <peff@peff.net>
Mon, 14 May 2018 16:22:48 +0000 (12:22 -0400)
committerJeff King <peff@peff.net>
Tue, 22 May 2018 03:55:12 +0000 (23:55 -0400)
If we have a tree that points to a .gitmodules blob but
don't have that blob, we can't check its contents. This
produces an fsck error when we encounter it.

But in the case of a promisor object, this absence is
expected, and we must not complain. Note that this can
technically circumvent our transfer.fsckObjects check.
Imagine a client fetches a tree, but not the matching
.gitmodules blob. An fsck of the incoming objects will show
that we don't have enough information. Later, we do fetch
the actual blob. But we have no idea that it's a .gitmodules
file.

The only ways to get around this would be to re-scan all of
the existing trees whenever new ones enter (which is
expensive), or to somehow persist the gitmodules_found set
between fsck runs (which is complicated).

In practice, it's probably OK to ignore the problem. Any
repository which has all of the objects (including the one
serving the promisor packs) can perform the checks. Since
promisor packs are inherently about a hierarchical topology
in which clients rely on upstream repositories, those
upstream repositories can protect all of their downstream
clients from broken objects.

Signed-off-by: Jeff King <peff@peff.net>
fsck.c
diff --git a/fsck.c b/fsck.c
index 105b3e7f48ff00793f924983214e008a38b3c6fe..a91e6ce70c75d122ca4538046b2af904918fa681 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -11,6 +11,7 @@
 #include "sha1-array.h"
 #include "decorate.h"
 #include "oidset.h"
+#include "packfile.h"
 
 static struct oidset gitmodules_found = OIDSET_INIT;
 static struct oidset gitmodules_done = OIDSET_INIT;
@@ -974,6 +975,8 @@ int fsck_finish(struct fsck_options *options)
 
                buf = read_sha1_file(oid->hash, &type, &size);
                if (!buf) {
+                       if (is_promisor_object(&blob->object.oid))
+                               continue;
                        ret |= report(options, &blob->object,
                                      FSCK_MSG_GITMODULES_MISSING,
                                      "unable to read .gitmodules blob");