Thread (7 messages) flat view 7 messages, 6 authors, 2016-06-15

Re: [PATCH] Add option -b/--branch to clone for select a new HEAD

From: Björn Steinbrink <hidden>
Date: 2016-06-15 22:47:19

Possibly related (same subject, not in this thread)

On 2009.08.25 23:27:47 +0400, Kirill A. Korinskiy wrote:
quoted hunk ↗ jump to hunk
Sometimes (especially on production systems) we need to use only one
remote branch for building software. It's really annoying to clone
origin and then switch branch by hand everytime. So this patch
provides functionality to clone a remote branch with one command
without using checkout after clone.

Signed-off-by: Kirill A. Korinskiy <redacted>
---
 Documentation/git-clone.txt |    4 ++++
 builtin-clone.c             |   23 ++++++++++++++++++++---
 t/t5706-clone-branch.sh     |   31 +++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 3 deletions(-)
 create mode 100755 t/t5706-clone-branch.sh
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 2c63a0f..50446d2 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -127,6 +127,10 @@ objects from the source repository into a pack in the cloned repository.
 	Instead of using the remote name 'origin' to keep track
 	of the upstream repository, use <name>.
 
+--branch <name>::
+-b <name>::
+	Instead of using the remote HEAD as master, use <name> branch.
Hm, that's no good. The branch won't be called master, nor is HEAD used
as "master" anyway. If the remote repo's HEAD references refs/heads/foo,
you'll get refs/heads/foo locally as well, not "master", but see below.

Maybe: Create a local branch head for <name> instead of the branch
referenced by the remote repo's HEAD.
quoted hunk ↗ jump to hunk
@@ -65,6 +66,8 @@ static struct option builtin_clone_options[] = {
 		   "reference repository"),
 	OPT_STRING('o', "origin", &option_origin, "branch",
 		   "use <branch> instead of 'origin' to track upstream"),
+	OPT_STRING('b', "branch", &option_branch, "branch",
+		   "use <branch> from 'origin' as HEAD"),
Using 'origin' there is unfortunate, as using "--origin foo" would make
clone call the remote "foo" instead of "origin". And it's not really
used "as" HEAD, but instead of the remote repo's HEAD to determine which
local branch head to create. Though I guess this affect the
refs/remotes/<remote>/HEAD symref as well?
quoted hunk ↗ jump to hunk
@@ -518,7 +521,21 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 
 		mapped_refs = write_remote_refs(refs, refspec, reflog_msg.buf);
 
-		remote_head = find_ref_by_name(refs, "HEAD");
+		if (option_branch) {
+			strbuf_addf(&branch_head, "%s%s", src_ref_prefix, option_branch);
+
+			remote_head = find_ref_by_name(refs, branch_head.buf);
+		}
+
+		if (!remote_head) {
+			if (option_branch)
+				warning("Remote branch %s not found in upstream %s"
+					", using HEAD instead",
+					option_branch, option_origin);
+
+			remote_head = find_ref_by_name(refs, "HEAD");
+		}
+
 		head_points_at = guess_remote_head(remote_head, mapped_refs, 0);
This would still pick refs/heads/master if refs/heads/master and
refs/heads/<branch> reference the same commit. That's due to the check
in guess_remote_head() which prefers refs/heads/master over all other
refs. While this is acceptable for the HEAD lookup, I'd treat that as a
bug for this new option.
quoted hunk ↗ jump to hunk
 	}
 	else {
diff --git a/t/t5706-clone-branch.sh b/t/t5706-clone-branch.sh
new file mode 100755
index 0000000..8d83ac8
--- /dev/null
+++ b/t/t5706-clone-branch.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+test_description='branch clone options'
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+
+	mkdir parent &&
+	(cd parent && git init &&
+	 echo one >file && git add file &&
+	 git commit -m one && git checkout -b two &&
+	 echo two >f && git add f && git commit -m two &&
+	 git checkout master)
+
+'
+
+test_expect_success 'clone' '
+
+	git clone parent clone &&
+	(cd clone && git rev-parse --verify refs/remotes/origin/master)
+
+'
+
+test_expect_success 'clone -b' '
+
+	git clone -b two parent clone-b &&
+	(cd clone-b && test $(git rev-parse --verify HEAD) = $(git rev-parse --verify refs/remotes/origin/two))
This should probably check not just that HEAD resolves to the same
commit as refs/remotes/origin/two, but that HEAD references
refs/heads/two as well, even if the remote's refs/heads/master
references the same commit as refs/heads/two (see above).

Björn
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help