Thread (4 messages) flat view 4 messages, 3 authors, 2016-06-15

[PATCHv2] clone: fix refspec on "--single-branch" option

From: Ralf Thielow <hidden>
Date: 2016-06-15 22:54:45
Subsystem: the rest · Maintainer: Linus Torvalds

Possibly related (same subject, not in this thread)

After a repo was cloned with the "--single-branch"
option, the configured refspec looks like
"+refs/heads/*:refs/remotes/origin/*".
After fetching from this repo again, it'll receive
all refs instead of just the ref from the single
branch. Fixing this by configure exactly the ref
of the branch the user specified in the "git clone"
command.

Signed-off-by: Ralf Thielow <redacted>
---
Alternatively, if you can move the logic to set up this
configuration further down so that it happens after we talked to the
other side and figured out remote_head_points_at, you could instead
set it up to keep a single remote tracking branch.

Even if you did so, guess_remote_head() may not find any branch when
the other repository's HEAD is detached, so you would need to decide
what to do in such a case, and "fetch and integrate their HEAD
without using any remote tracking branch" may be a reasonable thing
to do in such a case.
This second version now covers also the "--single-branch"
option when it was called without "--branch". It also covers
the "detached HEAD" case.
I've tested all the use-cases that have been described above and it works
as expected with this patch. But there's just one thing. It fetches
also all the tags even if they're not on this branch. I'm still in the
"learning process", perhaps someone else can fix this problem or point
me to the reason. 
I think it comes from "transport_fetch_refs(transport, mapped_refs);"
on line 813 which is called with a full "+refs/heads/*:refs/remotes/origin/*"
refspec. Thanks

 builtin/clone.c | 41 +++++++++++++++++++++++++++--------------
 1 Datei geändert, 27 Zeilen hinzugefügt(+), 14 Zeilen entfernt(-)
diff --git a/builtin/clone.c b/builtin/clone.c
index 5e8f3ba..3ddf5ab 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -755,20 +755,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	}
 
 	strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
-
-	if (option_mirror || !option_bare) {
-		/* Configure the remote */
-		strbuf_addf(&key, "remote.%s.fetch", option_origin);
-		git_config_set_multivar(key.buf, value.buf, "^$", 0);
-		strbuf_reset(&key);
-
-		if (option_mirror) {
-			strbuf_addf(&key, "remote.%s.mirror", option_origin);
-			git_config_set(key.buf, "true");
-			strbuf_reset(&key);
-		}
-	}
-
 	strbuf_addf(&key, "remote.%s.url", option_origin);
 	git_config_set(key.buf, repo);
 	strbuf_reset(&key);
@@ -853,6 +839,33 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 					      "refs/heads/master");
 	}
 
+	if (option_mirror || !option_bare) {
+		strbuf_reset(&value);
+		if (option_single_branch) {
+			if (option_branch)
+				strbuf_addf(&value, "+%s%s:%s%s", src_ref_prefix, option_branch,
+						branch_top.buf, option_branch);
+			else if (remote_head_points_at)
+					strbuf_addf(&value, "+%s:%s%s", our_head_points_at->name,
+									branch_top.buf, prettify_refname(remote_head_points_at->name));
+		} else {
+			strbuf_addf(&value, "+%s*:%s*", src_ref_prefix, branch_top.buf);
+		}
+		/* Configure the remote */
+		if (value.len) {
+			strbuf_reset(&key);
+			strbuf_addf(&key, "remote.%s.fetch", option_origin);
+			git_config_set_multivar(key.buf, value.buf, "^$", 0);
+			strbuf_reset(&key);
+
+			if (option_mirror) {
+				strbuf_addf(&key, "remote.%s.mirror", option_origin);
+				git_config_set(key.buf, "true");
+				strbuf_reset(&key);
+			}
+		}
+	}
+
 	if (is_local)
 		clone_local(path, git_dir);
 	else if (refs && complete_refs_before_fetch)
-- 
1.7.12.395.g6b149ce.dirty
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help