Merge branch 'jt/connectivity-check-optim-in-partial-clone'

Unneeded connectivity check is now disabled in a partial clone when
fetching into it.

* jt/connectivity-check-optim-in-partial-clone:
  fetch: forgo full connectivity check if --filter
  connected: verify promisor-ness of partial clone
This commit is contained in:
Junio C Hamano 2020-02-14 12:54:21 -08:00
commit 8fb3945037
4 changed files with 33 additions and 13 deletions

View File

@ -673,7 +673,7 @@ static void update_remote_refs(const struct ref *refs,
const char *msg, const char *msg,
struct transport *transport, struct transport *transport,
int check_connectivity, int check_connectivity,
int check_refs_only) int check_refs_are_promisor_objects_only)
{ {
const struct ref *rm = mapped_refs; const struct ref *rm = mapped_refs;
@ -682,7 +682,8 @@ static void update_remote_refs(const struct ref *refs,
opt.transport = transport; opt.transport = transport;
opt.progress = transport->progress; opt.progress = transport->progress;
opt.check_refs_only = !!check_refs_only; opt.check_refs_are_promisor_objects_only =
!!check_refs_are_promisor_objects_only;
if (check_connected(iterate_ref_map, &rm, &opt)) if (check_connected(iterate_ref_map, &rm, &opt))
die(_("remote did not send all necessary objects")); die(_("remote did not send all necessary objects"));

View File

@ -906,8 +906,17 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
url = xstrdup("foreign"); url = xstrdup("foreign");
if (!connectivity_checked) { if (!connectivity_checked) {
struct check_connected_options opt = CHECK_CONNECTED_INIT;
if (filter_options.choice)
/*
* Since a filter is specified, objects indirectly
* referenced by refs are allowed to be absent.
*/
opt.check_refs_are_promisor_objects_only = 1;
rm = ref_map; rm = ref_map;
if (check_connected(iterate_ref_map, &rm, NULL)) { if (check_connected(iterate_ref_map, &rm, &opt)) {
rc = error(_("%s did not send all necessary objects\n"), url); rc = error(_("%s did not send all necessary objects\n"), url);
goto abort; goto abort;
} }

View File

@ -52,19 +52,28 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
strbuf_release(&idx_file); strbuf_release(&idx_file);
} }
if (opt->check_refs_only) { if (opt->check_refs_are_promisor_objects_only) {
/* /*
* For partial clones, we don't want to have to do a regular * For partial clones, we don't want to have to do a regular
* connectivity check because we have to enumerate and exclude * connectivity check because we have to enumerate and exclude
* all promisor objects (slow), and then the connectivity check * all promisor objects (slow), and then the connectivity check
* itself becomes a no-op because in a partial clone every * itself becomes a no-op because in a partial clone every
* object is a promisor object. Instead, just make sure we * object is a promisor object. Instead, just make sure we
* received the objects pointed to by each wanted ref. * received, in a promisor packfile, the objects pointed to by
* each wanted ref.
*/ */
do { do {
if (!repo_has_object_file_with_flags(the_repository, &oid, struct packed_git *p;
OBJECT_INFO_SKIP_FETCH_OBJECT))
return 1; for (p = get_all_packs(the_repository); p; p = p->next) {
if (!p->pack_promisor)
continue;
if (find_pack_entry_one(oid.hash, p))
goto promisor_pack_found;
}
return 1;
promisor_pack_found:
;
} while (!fn(cb_data, &oid)); } while (!fn(cb_data, &oid));
return 0; return 0;
} }

View File

@ -48,12 +48,13 @@ struct check_connected_options {
unsigned is_deepening_fetch : 1; unsigned is_deepening_fetch : 1;
/* /*
* If non-zero, only check the top-level objects referenced by the * If non-zero, only check that the top-level objects referenced by the
* wanted refs (passed in as cb_data). This is useful for partial * wanted refs (passed in as cb_data) are promisor objects. This is
* clones, where enumerating and excluding all promisor objects is very * useful for partial clones, where enumerating and excluding all
* slow and the commit-walk itself becomes a no-op. * promisor objects is very slow and the commit-walk itself becomes a
* no-op.
*/ */
unsigned check_refs_only : 1; unsigned check_refs_are_promisor_objects_only : 1;
}; };
#define CHECK_CONNECTED_INIT { 0 } #define CHECK_CONNECTED_INIT { 0 }