Skip to content

Commit dfa33a2

Browse files
steadmongitster
authored andcommitted
clone: do faster object check for partial clones
For partial clones, doing a full connectivity check is wasteful; we skip promisor objects (which, for a partial clone, is all known objects), and enumerating them all to exclude them from the connectivity check can take a significant amount of time on large repos. At most, we want to make sure that we get the objects referred to by any wanted refs. For partial clones, just check that these objects were transferred. Signed-off-by: Josh Steadmon <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 041f5ea commit dfa33a2

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

builtin/clone.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,7 +657,8 @@ static void update_remote_refs(const struct ref *refs,
657657
const char *branch_top,
658658
const char *msg,
659659
struct transport *transport,
660-
int check_connectivity)
660+
int check_connectivity,
661+
int check_refs_only)
661662
{
662663
const struct ref *rm = mapped_refs;
663664

@@ -666,6 +667,7 @@ static void update_remote_refs(const struct ref *refs,
666667

667668
opt.transport = transport;
668669
opt.progress = transport->progress;
670+
opt.check_refs_only = !!check_refs_only;
669671

670672
if (check_connected(iterate_ref_map, &rm, &opt))
671673
die(_("remote did not send all necessary objects"));
@@ -1224,7 +1226,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
12241226

12251227
update_remote_refs(refs, mapped_refs, remote_head_points_at,
12261228
branch_top.buf, reflog_msg.buf, transport,
1227-
!is_local);
1229+
!is_local, filter_options.choice);
12281230

12291231
update_head(our_head_points_at, remote_head, reflog_msg.buf);
12301232

connected.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "cache.h"
2+
#include "object-store.h"
23
#include "run-command.h"
34
#include "sigchain.h"
45
#include "connected.h"
@@ -49,6 +50,22 @@ int check_connected(oid_iterate_fn fn, void *cb_data,
4950
strbuf_release(&idx_file);
5051
}
5152

53+
if (opt->check_refs_only) {
54+
/*
55+
* For partial clones, we don't want to have to do a regular
56+
* connectivity check because we have to enumerate and exclude
57+
* all promisor objects (slow), and then the connectivity check
58+
* itself becomes a no-op because in a partial clone every
59+
* object is a promisor object. Instead, just make sure we
60+
* received the objects pointed to by each wanted ref.
61+
*/
62+
do {
63+
if (!repo_has_object_file(the_repository, &oid))
64+
return 1;
65+
} while (!fn(cb_data, &oid));
66+
return 0;
67+
}
68+
5269
if (opt->shallow_file) {
5370
argv_array_push(&rev_list.args, "--shallow-file");
5471
argv_array_push(&rev_list.args, opt->shallow_file);

connected.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ struct check_connected_options {
4646
* during a fetch.
4747
*/
4848
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.
55+
*/
56+
unsigned check_refs_only : 1;
4957
};
5058

5159
#define CHECK_CONNECTED_INIT { 0 }

0 commit comments

Comments
 (0)