Thread (7 messages) flat view 7 messages, 3 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.26 15:53:58 +0400, Kirill A. Korinskiy wrote:
At Wed, 26 Aug 2009 00:36:37 +0200,
Björn Steinbrink [off-list ref] wrote:

quoted
quoted
@@ -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.
My english is not a good and I don't understand it, sorry.
guess_remote_head() compares the object ids from remote_head and all of
the remote's refs to guess which is the right one.

Let's say that the repo has:

refs/heads/master: object1
refs/heads/foo: object2
refs/heads/bar: object1

If you do "git clone -b foo ...", then remote_head->old_sha1 will be
"object2". guess_remote_head() compares that to all the remote heads. In
this case, it will find refs/heads/foo (as expected).

But when you do "git clone -b bar", then remote_head->old_sha1 will be
"object1". And guess_remote_head() will then take refs/heads/master,
as it prefers that one.

doener@atjola:h $ mkdir a; cd a; git init
Initialized empty Git repository in /home/doener/h/a/.git/
doener@atjola:a (master) $ git commit --allow-empty -m init
[master (root-commit) a7a0b54] init
doener@atjola:a (master) $ git branch bar
doener@atjola:a (master) $ git checkout -b foo
Switched to a new branch 'foo'
doener@atjola:a (foo) $ git commit --allow-empty -m on_foo
[foo 375047e] on_foo
doener@atjola:a (foo) $ cd ..
doener@atjola:h $ (git clone -b foo a foo; cd foo; git branch)
Initialized empty Git repository in /home/doener/h/foo/.git/
* foo
doener@atjola:h $ (git clone -b bar a bar; cd bar; git branch)
Initialized empty Git repository in /home/doener/h/bar/.git/
* master


That said, I actually wonder why you don't simple set HEAD in the
original repo so that you get whichever branch you want by default
anyway.

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