summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2020-02-14 20:54:21 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-02-14 20:54:21 (GMT)
commit8fb39450371ce9a89e0f551c94f02e73819f8325 (patch)
tree49d4c67e4904dd54809a9b3aa9f76875c8ed3d39
parent09e48400a3537db841b94790f070c4b843fc0bd0 (diff)
parent2df1aa239cd50698ab3e0c2cb18b9c1d2f0e44d7 (diff)
downloadgit-8fb39450371ce9a89e0f551c94f02e73819f8325.zip
git-8fb39450371ce9a89e0f551c94f02e73819f8325.tar.gz
git-8fb39450371ce9a89e0f551c94f02e73819f8325.tar.bz2
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
-rw-r--r--builtin/clone.c5
-rw-r--r--builtin/fetch.c11
-rw-r--r--connected.c19
-rw-r--r--connected.h11
4 files changed, 33 insertions, 13 deletions
diff --git a/builtin/clone.c b/builtin/clone.c
index 0fc89ae..0516181 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -673,7 +673,7 @@ static void update_remote_refs(const struct ref *refs,
const char *msg,
struct transport *transport,
int check_connectivity,
- int check_refs_only)
+ int check_refs_are_promisor_objects_only)
{
const struct ref *rm = mapped_refs;
@@ -682,7 +682,8 @@ static void update_remote_refs(const struct ref *refs,
opt.transport = transport;
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))
die(_("remote did not send all necessary objects"));
diff --git a/builtin/fetch.c b/builtin/fetch.c
index b4c6d92..6fb5032 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -906,8 +906,17 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
url = xstrdup("foreign");
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;
- 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);
goto abort;
}
diff --git a/connected.c b/connected.c
index c337f5f..7e9bd1b 100644
--- a/connected.c
+++ b/connected.c
@@ -52,19 +52,28 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
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
* connectivity check because we have to enumerate and exclude
* all promisor objects (slow), and then the connectivity check
* itself becomes a no-op because in a partial clone every
* 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 {
- if (!repo_has_object_file_with_flags(the_repository, &oid,
- OBJECT_INFO_SKIP_FETCH_OBJECT))
- return 1;
+ struct packed_git *p;
+
+ 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));
return 0;
}
diff --git a/connected.h b/connected.h
index ce2e7d8..eba5c26 100644
--- a/connected.h
+++ b/connected.h
@@ -48,12 +48,13 @@ struct check_connected_options {
unsigned is_deepening_fetch : 1;
/*
- * If non-zero, only check the top-level objects referenced by the
- * wanted refs (passed in as cb_data). This is useful for partial
- * clones, where enumerating and excluding all promisor objects is very
- * slow and the commit-walk itself becomes a no-op.
+ * If non-zero, only check that the top-level objects referenced by the
+ * wanted refs (passed in as cb_data) are promisor objects. This is
+ * useful for partial clones, where enumerating and excluding all
+ * 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 }