Skip to content

Commit 6f48d39

Browse files
pcloudsgitster
authored andcommitted
clone: delay cloning until after remote HEAD checking
This gives us an opportunity to abort the command during remote HEAD check without wasting much bandwidth. Cloning with remote-helper remains before the check because the remote helper updates mapped_refs, which is necessary for remote ref checks. foreign_vcs field is used to indicate the transport is handled by remote helper. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 960b7d1 commit 6f48d39

File tree

2 files changed

+31
-28
lines changed

2 files changed

+31
-28
lines changed

builtin/clone.c

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -364,13 +364,8 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
364364
closedir(dir);
365365
}
366366

367-
static const struct ref *clone_local(const char *src_repo,
368-
const char *dest_repo)
367+
static void clone_local(const char *src_repo, const char *dest_repo)
369368
{
370-
const struct ref *ret;
371-
struct remote *remote;
372-
struct transport *transport;
373-
374369
if (option_shared) {
375370
struct strbuf alt = STRBUF_INIT;
376371
strbuf_addf(&alt, "%s/objects", src_repo);
@@ -386,13 +381,8 @@ static const struct ref *clone_local(const char *src_repo,
386381
strbuf_release(&dest);
387382
}
388383

389-
remote = remote_get(src_repo);
390-
transport = transport_get(remote, src_repo);
391-
ret = transport_get_remote_refs(transport);
392-
transport_disconnect(transport);
393384
if (0 <= option_verbosity)
394385
printf(_("done.\n"));
395-
return ret;
396386
}
397387

398388
static const char *junk_work_tree;
@@ -619,6 +609,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
619609
struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
620610
struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
621611
struct transport *transport = NULL;
612+
struct remote *remote;
622613
int err = 0;
623614

624615
struct refspec *refspec;
@@ -773,13 +764,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
773764

774765
strbuf_reset(&value);
775766

776-
if (is_local) {
777-
refs = clone_local(path, git_dir);
778-
mapped_refs = wanted_peer_refs(refs, refspec);
779-
} else {
780-
struct remote *remote = remote_get(option_origin);
781-
transport = transport_get(remote, remote->url[0]);
767+
remote = remote_get(option_origin);
768+
transport = transport_get(remote, remote->url[0]);
782769

770+
if (!is_local) {
783771
if (!transport->get_refs_list || !transport->fetch)
784772
die(_("Don't know how to clone %s"), transport->url);
785773

@@ -796,14 +784,23 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
796784
if (option_upload_pack)
797785
transport_set_option(transport, TRANS_OPT_UPLOADPACK,
798786
option_upload_pack);
799-
800-
refs = transport_get_remote_refs(transport);
801-
if (refs) {
802-
mapped_refs = wanted_peer_refs(refs, refspec);
803-
transport_fetch_refs(transport, mapped_refs);
804-
}
805787
}
806788

789+
refs = transport_get_remote_refs(transport);
790+
mapped_refs = refs ? wanted_peer_refs(refs, refspec) : NULL;
791+
792+
/*
793+
* mapped_refs may be updated if transport-helper is used so
794+
* we need fetch it early because remote_head code below
795+
* relies on it.
796+
*
797+
* for normal clones, transport_get_remote_refs() should
798+
* return reliable ref set, we can delay cloning until after
799+
* remote HEAD check.
800+
*/
801+
if (!is_local && remote->foreign_vcs && refs)
802+
transport_fetch_refs(transport, mapped_refs);
803+
807804
if (refs) {
808805
remote_head = find_ref_by_name(refs, "HEAD");
809806
remote_head_points_at =
@@ -838,15 +835,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
838835
"refs/heads/master");
839836
}
840837

838+
if (is_local)
839+
clone_local(path, git_dir);
840+
else if (refs && !remote->foreign_vcs)
841+
transport_fetch_refs(transport, mapped_refs);
842+
841843
update_remote_refs(refs, mapped_refs, remote_head_points_at,
842844
branch_top.buf, reflog_msg.buf);
843845

844846
update_head(our_head_points_at, remote_head, reflog_msg.buf);
845847

846-
if (transport) {
847-
transport_unlock_pack(transport);
848-
transport_disconnect(transport);
849-
}
848+
transport_unlock_pack(transport);
849+
transport_disconnect(transport);
850850

851851
err = checkout();
852852

transport.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,8 +895,10 @@ struct transport *transport_get(struct remote *remote, const char *url)
895895

896896
while (is_urlschemechar(p == url, *p))
897897
p++;
898-
if (!prefixcmp(p, "::"))
898+
if (!prefixcmp(p, "::")) {
899899
helper = xstrndup(url, p - url);
900+
remote->foreign_vcs = helper;
901+
}
900902
}
901903

902904
if (helper) {
@@ -938,6 +940,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
938940
char *handler = xmalloc(len + 1);
939941
handler[len] = 0;
940942
strncpy(handler, url, len);
943+
remote->foreign_vcs = handler;
941944
transport_helper_init(ret, handler);
942945
}
943946

0 commit comments

Comments
 (0)