Merge branch 'jt/transfer-fsck-with-promissor' into next
authorJunio C Hamano <gitster@pobox.com>
Thu, 15 Mar 2018 22:11:00 +0000 (15:11 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 15 Mar 2018 22:11:01 +0000 (15:11 -0700)
The transfer.fsckobjects configuration tells "git fetch" to
validate the data and connected-ness of objects in the received
pack; the code to perform this check has been taught about the
narrow clone's convention that missing objects that are reachable
from objects in a pack that came from a promissor remote is OK.

* jt/transfer-fsck-with-promissor:
fetch-pack: do not check links for partial fetch
index-pack: support checking objects but not links

1  2 
fetch-pack.c
diff --combined fetch-pack.c
index 2ea358861dacb91697137dc22891122e35b6a472,1d6117565c2067460efc50aa4e6ca2ecb167a976..52932b37f8dce61296c37d6fa821d564f0f4a38b
@@@ -711,28 -711,6 +711,28 @@@ static void mark_alternate_complete(str
        mark_complete(&obj->oid);
  }
  
 +struct loose_object_iter {
 +      struct oidset *loose_object_set;
 +      struct ref *refs;
 +};
 +
 +/*
 + *  If the number of refs is not larger than the number of loose objects,
 + *  this function stops inserting.
 + */
 +static int add_loose_objects_to_set(const struct object_id *oid,
 +                                  const char *path,
 +                                  void *data)
 +{
 +      struct loose_object_iter *iter = data;
 +      oidset_insert(iter->loose_object_set, oid);
 +      if (iter->refs == NULL)
 +              return 1;
 +
 +      iter->refs = iter->refs->next;
 +      return 0;
 +}
 +
  static int everything_local(struct fetch_pack_args *args,
                            struct ref **refs,
                            struct ref **sought, int nr_sought)
        int retval;
        int old_save_commit_buffer = save_commit_buffer;
        timestamp_t cutoff = 0;
 +      struct oidset loose_oid_set = OIDSET_INIT;
 +      int use_oidset = 0;
 +      struct loose_object_iter iter = {&loose_oid_set, *refs};
 +
 +      /* Enumerate all loose objects or know refs are not so many. */
 +      use_oidset = !for_each_loose_object(add_loose_objects_to_set,
 +                                          &iter, 0);
  
        save_commit_buffer = 0;
  
        for (ref = *refs; ref; ref = ref->next) {
                struct object *o;
 +              unsigned int flags = OBJECT_INFO_QUICK;
  
 -              if (!has_object_file_with_flags(&ref->old_oid,
 -                                              OBJECT_INFO_QUICK))
 -                      continue;
 +              if (use_oidset &&
 +                  !oidset_contains(&loose_oid_set, &ref->old_oid)) {
 +                      /*
 +                       * I know this does not exist in the loose form,
 +                       * so check if it exists in a non-loose form.
 +                       */
 +                      flags |= OBJECT_INFO_IGNORE_LOOSE;
 +              }
  
 +              if (!has_object_file_with_flags(&ref->old_oid, flags))
 +                      continue;
                o = parse_object(&ref->old_oid);
                if (!o)
                        continue;
                }
        }
  
 +      oidset_clear(&loose_oid_set);
 +
        if (!args->no_dependents) {
                if (!args->deepen) {
                        for_each_ref(mark_complete_oid, NULL);
@@@ -925,8 -886,17 +925,17 @@@ static int get_pack(struct fetch_pack_a
            ? fetch_fsck_objects
            : transfer_fsck_objects >= 0
            ? transfer_fsck_objects
-           : 0)
-               argv_array_push(&cmd.args, "--strict");
+           : 0) {
+               if (args->from_promisor)
+                       /*
+                        * We cannot use --strict in index-pack because it
+                        * checks both broken objects and links, but we only
+                        * want to check for broken objects.
+                        */
+                       argv_array_push(&cmd.args, "--fsck-objects");
+               else
+                       argv_array_push(&cmd.args, "--strict");
+       }
  
        cmd.in = demux.out;
        cmd.git_cmd = 1;