Teach fsck to not treat missing objects indirectly pointed to by refs as
an error when extensions.lazyobject is set.

Signed-off-by: Jonathan Tan <jonathanta...@google.com>
---
 builtin/fsck.c         | 11 +++++++++++
 t/t0410-lazy-object.sh | 27 +++++++++++++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/builtin/fsck.c b/builtin/fsck.c
index 38ed630d8..19681c5b3 100644
--- a/builtin/fsck.c
+++ b/builtin/fsck.c
@@ -149,6 +149,15 @@ static int mark_object(struct object *obj, int type, void 
*data, struct fsck_opt
                return 0;
        obj->flags |= REACHABLE;
        if (!(obj->flags & HAS_OBJ)) {
+               if (repository_format_lazy_object)
+                       /*
+                        * Return immediately; this is not an error, and further
+                        * recursion does not need to be performed on this
+                        * object since it is missing (so it does not need to be
+                        * added to "pending").
+                        */
+                       return 0;
+
                if (parent && !has_object_file(&obj->oid)) {
                        printf("broken link from %7s %s\n",
                                 printable_type(parent), 
describe_object(parent));
@@ -212,6 +221,8 @@ static void check_reachable_object(struct object *obj)
         * do a full fsck
         */
        if (!(obj->flags & HAS_OBJ)) {
+               if (repository_format_lazy_object)
+                       return;
                if (has_sha1_pack(obj->oid.hash))
                        return; /* it is in pack - forget about it */
                printf("missing %s %s\n", printable_type(obj),
diff --git a/t/t0410-lazy-object.sh b/t/t0410-lazy-object.sh
index 00e1b4a88..45f665a15 100755
--- a/t/t0410-lazy-object.sh
+++ b/t/t0410-lazy-object.sh
@@ -49,4 +49,31 @@ test_expect_success '...but succeeds if lazyobject is set' '
        git -C repo fsck
 '
 
+test_expect_success 'fsck fails on lazy object indirectly pointed to by ref' '
+       rm -rf repo &&
+       test_create_repo repo &&
+       test_commit -C repo 1 &&
+       test_commit -C repo 2 &&
+       test_commit -C repo 3 &&
+       git -C repo tag -a annotated_tag -m "annotated tag" &&
+
+       C=$(git -C repo rev-parse 1) &&
+       T=$(git -C repo rev-parse 2^{tree}) &&
+       B=$(git hash-object repo/3.t) &&
+       AT=$(git -C repo rev-parse annotated_tag) &&
+
+       # missing commit, tree, blob, and tag
+       delete_object repo "$C" &&
+       delete_object repo "$T" &&
+       delete_object repo "$B" &&
+       delete_object repo "$AT" &&
+       test_must_fail git -C repo fsck
+'
+
+test_expect_success '...but succeeds if lazyobject is set' '
+       git -C repo config core.repositoryformatversion 1 &&
+       git -C repo config extensions.lazyobject "arbitrary string" &&
+       git -C repo fsck
+'
+
 test_done
-- 
2.14.0.rc1.383.gd1ce394fe2-goog

Reply via email to