Takuto Ikuta <tikuta@xxxxxxxxxxxx> writes: > +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 and returns false. > + */ > +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; > +} That's clever. By traversing the refs list as you iterate over the loose objects, you do not do any unnecessary work ;-) Thanks for working on this. > @@ -719,16 +741,31 @@ static int everything_local(struct fetch_pack_args *args, > 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;