git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v3 06/10] clone: delay cloning until after remote HEAD checking

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Jan 10, 2012, 09:57 UTC
Message-ID
<1326189427-20800-7-git-send-email-pclouds@gmail.com>
In-Reply-To
<1326023188-15559-1-git-send-email-pclouds@gmail.com>

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.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 I'm not familiar with remote-helper to see if there's any better way
 to do this..
 builtin/clone.c |   54 +++++++++++++++++++++++++++---------------------------
 transport.c     |    5 ++++-
 2 files changed, 31 insertions(+), 28 deletions(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index 73d07ed..05224d7 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -361,13 +361,8 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest,
 	closedir(dir);
 }
 
-static const struct ref *clone_local(const char *src_repo,
-				     const char *dest_repo)
+static void clone_local(const char *src_repo, const char *dest_repo)
 {
-	const struct ref *ret;
-	struct remote *remote;
-	struct transport *transport;
-
 	if (option_shared) {
 		struct strbuf alt = STRBUF_INIT;
 		strbuf_addf(&alt, "%s/objects", src_repo);
@@ -383,13 +378,8 @@ static const struct ref *clone_local(const char *src_repo,
 		strbuf_release(&dest);
 	}
 
-	remote = remote_get(src_repo);
-	transport = transport_get(remote, src_repo);
-	ret = transport_get_remote_refs(transport);
-	transport_disconnect(transport);
 	if (0 <= option_verbosity)
 		printf(_("done.\n"));
-	return ret;
 }
 
 static const char *junk_work_tree;
@@ -576,6 +566,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
 	struct transport *transport = NULL;
 	char *src_ref_prefix = "refs/heads/";
+	struct remote *remote;
 	int err = 0;
 
 	struct refspec *refspec;
@@ -727,13 +718,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 	strbuf_reset(&value);
 
-	if (is_local) {
-		refs = clone_local(path, git_dir);
-		mapped_refs = wanted_peer_refs(refs, refspec);
-	} else {
-		struct remote *remote = remote_get(option_origin);
-		transport = transport_get(remote, remote->url[0]);
+	remote = remote_get(option_origin);
+	transport = transport_get(remote, remote->url[0]);
 
+	if (!is_local) {
 		if (!transport->get_refs_list || !transport->fetch)
 			die(_("Don't know how to clone %s"), transport->url);
 
@@ -748,14 +736,23 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 		if (option_upload_pack)
 			transport_set_option(transport, TRANS_OPT_UPLOADPACK,
 					     option_upload_pack);
-
-		refs = transport_get_remote_refs(transport);
-		if (refs) {
-			mapped_refs = wanted_peer_refs(refs, refspec);
-			transport_fetch_refs(transport, mapped_refs);
-		}
 	}
 
+	refs = transport_get_remote_refs(transport);
+	mapped_refs = refs ? wanted_peer_refs(refs, refspec) : NULL;
+
+	/*
+	 * mapped_refs may be updated if transport-helper is used so
+	 * we need fetch it early because remote_head code below
+	 * relies on it.
+	 *
+	 * for normal clones, transport_get_remote_refs() should
+	 * return reliable ref set, we can delay cloning until after
+	 * remote HEAD check.
+	 */
+	if (!is_local && remote->foreign_vcs && refs)
+		transport_fetch_refs(transport, mapped_refs);
+
 	if (refs) {
 		remote_head = find_ref_by_name(refs, "HEAD");
 		remote_head_points_at =
@@ -790,15 +787,18 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 					      "refs/heads/master");
 	}
 
+	if (is_local)
+		clone_local(path, git_dir);
+	else if (refs && !remote->foreign_vcs)
+		transport_fetch_refs(transport, mapped_refs);
+
 	update_remote_refs(refs, mapped_refs, remote_head_points_at,
 			   branch_top.buf, reflog_msg.buf);
 
 	update_head(our_head_points_at, remote_head, reflog_msg.buf);
 
-	if (transport) {
-		transport_unlock_pack(transport);
-		transport_disconnect(transport);
-	}
+	transport_unlock_pack(transport);
+	transport_disconnect(transport);
 
 	err = checkout();
 
diff --git a/transport.c b/transport.c
index a99b7c9..aae9889 100644
--- a/transport.c
+++ b/transport.c
@@ -895,8 +895,10 @@ struct transport *transport_get(struct remote *remote, const char *url)
 
 		while (is_urlschemechar(p == url, *p))
 			p++;
-		if (!prefixcmp(p, "::"))
+		if (!prefixcmp(p, "::")) {
 			helper = xstrndup(url, p - url);
+			remote->foreign_vcs = helper;
+		}
 	}
 
 	if (helper) {
@@ -938,6 +940,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
 		char *handler = xmalloc(len + 1);
 		handler[len] = 0;
 		strncpy(handler, url, len);
+		remote->foreign_vcs = helper;
 		transport_helper_init(ret, handler);
 	}
 
-- 
1.7.3.1.256.g2539c.dirty
Previous: Nguyễn Thái Ngọc DuyNext: Junio C Hamano
Message 55 of 68 in “clone: allow detached checkout when --branch takes a tag”
  1. clone: allow detached checkout when --branch takes a tagNguyễn Thái Ngọc Duy, Jan 5, 2012
  2. Jeff KingJan 5, 2012
  3. Nguyen Thai Ngoc DuyJan 6, 2012
  4. Jeff KingJan 6, 2012
  5. Junio C HamanoJan 5, 2012
  6. Nguyen Thai Ngoc DuyJan 6, 2012
  7. 1/6 t5601: add &&Nguyễn Thái Ngọc Duy, Jan 8, 2012
  8. 2/6 clone: write detached HEAD in bare repositoriesNguyễn Thái Ngọc Duy, Jan 8, 2012
  9. 3/6 clone: factor out checkout codeNguyễn Thái Ngọc Duy, Jan 8, 2012
  10. Junio C HamanoJan 10, 2012
  11. Nguyen Thai Ngoc DuyJan 10, 2012
  12. Junio C HamanoJan 10, 2012
  13. Nguyen Thai Ngoc DuyJan 10, 2012
  14. 4/6 clone: --branch=<branch> always means refs/heads/<branch>Nguyễn Thái Ngọc Duy, Jan 8, 2012
  15. Junio C HamanoJan 10, 2012
  16. 5/6 clone: allow --branch to take a tagNguyễn Thái Ngọc Duy, Jan 8, 2012
  17. 6/6 clone: print advice on checking out detached HEADNguyễn Thái Ngọc Duy, Jan 8, 2012
  18. Junio C HamanoJan 10, 2012
  19. Nguyen Thai Ngoc DuyJan 10, 2012
  20. Junio C HamanoJan 10, 2012
  21. Nguyen Thai Ngoc DuyJan 10, 2012
  22. 00/10 nd/clone-detachedNguyễn Thái Ngọc Duy, Jan 10, 2012
  23. 00/10 nd/clone-detachedNguyễn Thái Ngọc Duy, Jan 13, 2012
  24. Junio C HamanoJan 13, 2012
  25. Nguyen Thai Ngoc DuyJan 14, 2012
  26. Junio C HamanoJan 14, 2012
  27. Nguyen Thai Ngoc DuyJan 14, 2012
  28. Junio C HamanoJan 15, 2012
  29. 00/10 nd/clone-detached rebase onto nd/clone-single-branchNguyễn Thái Ngọc Duy, Jan 16, 2012
  30. 01/10 t5601: add missing && cascadeNguyễn Thái Ngọc Duy, Jan 16, 2012
  31. 02/10 clone: write detached HEAD in bare repositoriesNguyễn Thái Ngọc Duy, Jan 16, 2012
  32. 03/10 clone: factor out checkout codeNguyễn Thái Ngọc Duy, Jan 16, 2012
  33. 04/10 clone: factor out HEAD update codeNguyễn Thái Ngọc Duy, Jan 16, 2012
  34. 05/10 clone: factor out remote ref writingNguyễn Thái Ngọc Duy, Jan 16, 2012
  35. 06/10 clone: delay cloning until after remote HEAD checkingNguyễn Thái Ngọc Duy, Jan 16, 2012
  36. 07/10 clone: --branch=<branch> always means refs/heads/<branch>Nguyễn Thái Ngọc Duy, Jan 16, 2012
  37. 08/10 clone: refuse to clone if --branch points to bogus refNguyễn Thái Ngọc Duy, Jan 16, 2012
  38. 09/10 clone: allow --branch to take a tagNguyễn Thái Ngọc Duy, Jan 16, 2012
  39. 10/10 clone: print advice on checking out detached HEADNguyễn Thái Ngọc Duy, Jan 16, 2012
  40. 01/10 t5601: add missing && cascadeNguyễn Thái Ngọc Duy, Jan 13, 2012
  41. 02/10 clone: write detached HEAD in bare repositoriesNguyễn Thái Ngọc Duy, Jan 13, 2012
  42. 03/10 clone: factor out checkout codeNguyễn Thái Ngọc Duy, Jan 13, 2012
  43. 04/10 clone: factor out HEAD update codeNguyễn Thái Ngọc Duy, Jan 13, 2012
  44. 05/10 clone: factor out remote ref writingNguyễn Thái Ngọc Duy, Jan 13, 2012
  45. 06/10 clone: delay cloning until after remote HEAD checkingNguyễn Thái Ngọc Duy, Jan 13, 2012
  46. 07/10 clone: --branch=<branch> always means refs/heads/<branch>Nguyễn Thái Ngọc Duy, Jan 13, 2012
  47. 08/10 clone: refuse to clone if --branch points to bogus refNguyễn Thái Ngọc Duy, Jan 13, 2012
  48. 09/10 clone: allow --branch to take a tagNguyễn Thái Ngọc Duy, Jan 13, 2012
  49. 10/10 clone: print advice on checking out detached HEADNguyễn Thái Ngọc Duy, Jan 13, 2012
  50. 01/10 t5601: add missing && cascadeNguyễn Thái Ngọc Duy, Jan 10, 2012
  51. 02/10 clone: write detached HEAD in bare repositoriesNguyễn Thái Ngọc Duy, Jan 10, 2012
  52. 03/10 clone: factor out checkout codeNguyễn Thái Ngọc Duy, Jan 10, 2012
  53. 04/10 clone: factor out HEAD update codeNguyễn Thái Ngọc Duy, Jan 10, 2012
  54. 05/10 clone: factor out remote ref writingNguyễn Thái Ngọc Duy, Jan 10, 2012
  55. 06/10 clone: delay cloning until after remote HEAD checkingNguyễn Thái Ngọc Duy, Jan 10, 2012
  56. Junio C HamanoJan 11, 2012
  57. Nguyen Thai Ngoc DuyJan 12, 2012
  58. Junio C HamanoJan 24, 2012
  59. Junio C HamanoJan 24, 2012
  60. Junio C HamanoJan 24, 2012
  61. Nguyen Thai Ngoc DuyJan 24, 2012
  62. 07/10 clone: --branch=<branch> always means refs/heads/<branch>Nguyễn Thái Ngọc Duy, Jan 10, 2012
  63. Junio C HamanoJan 11, 2012
  64. Nguyen Thai Ngoc DuyJan 12, 2012
  65. 08/10 clone: refuse to clone if --branch points to bogus refNguyễn Thái Ngọc Duy, Jan 10, 2012
  66. 09/10 clone: allow --branch to take a tagNguyễn Thái Ngọc Duy, Jan 10, 2012
  67. Junio C HamanoJan 11, 2012
  68. 10/10 clone: print advice on checking out detached HEADNguyễn Thái Ngọc Duy, Jan 10, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.