@matheusbsbs / matheus-bagliano / commits / 50033772d5
Fork 0

connected: verify promisor-ness of partial clone

Commit dfa33a298d ("clone: do faster object check for partial clones", 2019-04-21) optimized the connectivity check done when cloning with --filter to check only the existence of objects directly pointed to by refs. But this is not sufficient: they also need to be promisor objects. Make this check more robust by instead checking that these objects are promisor objects, that is, they appear in a promisor pack. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Jan 11, 2020 at 20:15 UTC 50033772d50ef3c4023d63561d20bc61db96500e
3 files changed +23 -12
builtin/clone.c
+3 -2
@@ -673,7 +673,7 @@ static void update_remote_refs(const struct ref *refs,
673 const char *msg,
674 struct transport *transport,
675 int check_connectivity,
676 - int check_refs_only)
676 + int check_refs_are_promisor_objects_only)
677 {
678 const struct ref *rm = mapped_refs;
679
@@ -682,7 +682,8 @@ static void update_remote_refs(const struct ref *refs,
682
683 opt.transport = transport;
684 opt.progress = transport->progress;
685 - opt.check_refs_only = !!check_refs_only;
685 + opt.check_refs_are_promisor_objects_only =
686 + !!check_refs_are_promisor_objects_only;
687
688 if (check_connected(iterate_ref_map, &rm, &opt))
689 die(_("remote did not send all necessary objects"));
connected.c
+14 -5
@@ -52,19 +52,28 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
52 strbuf_release(&idx_file);
53 }
54
55 - if (opt->check_refs_only) {
55 + if (opt->check_refs_are_promisor_objects_only) {
56 /*
57 * For partial clones, we don't want to have to do a regular
58 * connectivity check because we have to enumerate and exclude
59 * all promisor objects (slow), and then the connectivity check
60 * itself becomes a no-op because in a partial clone every
61 * object is a promisor object. Instead, just make sure we
62 - * received the objects pointed to by each wanted ref.
62 + * received, in a promisor packfile, the objects pointed to by
63 + * each wanted ref.
64 */
65 do {
65 - if (!repo_has_object_file_with_flags(the_repository, &oid,
66 - OBJECT_INFO_SKIP_FETCH_OBJECT))
67 - return 1;
66 + struct packed_git *p;
67 +
68 + for (p = get_all_packs(the_repository); p; p = p->next) {
69 + if (!p->pack_promisor)
70 + continue;
71 + if (find_pack_entry_one(oid.hash, p))
72 + goto promisor_pack_found;
73 + }
74 + return 1;
75 +promisor_pack_found:
76 + ;
77 } while (!fn(cb_data, &oid));
78 return 0;
79 }
connected.h
+6 -5
@@ -48,12 +48,13 @@ struct check_connected_options {
48 unsigned is_deepening_fetch : 1;
49
50 /*
51 - * If non-zero, only check the top-level objects referenced by the
52 - * wanted refs (passed in as cb_data). This is useful for partial
53 - * clones, where enumerating and excluding all promisor objects is very
54 - * slow and the commit-walk itself becomes a no-op.
51 + * If non-zero, only check that the top-level objects referenced by the
52 + * wanted refs (passed in as cb_data) are promisor objects. This is
53 + * useful for partial clones, where enumerating and excluding all
54 + * promisor objects is very slow and the commit-walk itself becomes a
55 + * no-op.
56 */
56 - unsigned check_refs_only : 1;
57 + unsigned check_refs_are_promisor_objects_only : 1;
58 };
59
60 #define CHECK_CONNECTED_INIT { 0 }