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

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

From
Björn Steinbrink <b.steinbrink@gmx.de>
Date
Aug 26, 2009, 15:50 UTC
Message-ID
<20090826155029.GA5750@atjola.homenet>
In-Reply-To
<1251298007-18693-1-git-send-email-catap@catap.ru>
On 2009.08.26 18:46:47 +0400, Kirill A. Korinskiy wrote:
Show 22 quoted lines
> @@ -518,8 +521,22 @@ 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");
> -		head_points_at = guess_remote_head(remote_head, mapped_refs, 0);
> +		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, 1);

Just setting "all" to 1 there is wrong. With "all" set to 1, guess_remote_head() returns a linked list of _all_ matching refs. The first entry in that list depends on the order of mapped_refs.

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) aa39247] init doener@atjola:a (master) $ git branch foo doener@atjola:a (master) $ 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 master a master; cd master; git branch)
Initialized empty Git repository in /home/doener/h/master/.git/
* foo
Here, "foo" was first in mapped_refs, and so "-b master" used that, too.

Using guess_remote_head() seems pretty wrong. With -b given, you don't want to guess anymore, you _know_ which one you want. Unfortunately, I don't see a straight-forward way to handle that (but I'm totally clueless about the code, so don't let me scare you ;-)).

Show 51 quoted lines
> diff --git a/t/t5706-clone-branch.sh b/t/t5706-clone-branch.sh
> new file mode 100755
> index 0000000..b5fec50
> --- /dev/null
> +++ b/t/t5706-clone-branch.sh
> @@ -0,0 +1,49 @@
> +#!/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 branch foo &&
> +	 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 &&
> +	test $(git rev-parse --verify HEAD) = \
> +	     $(git rev-parse --verify refs/remotes/origin/master) &&
> +	test $(git rev-parse --verify HEAD) != \
> +	     $(git rev-parse --verify refs/remotes/origin/two))
> +
> +
> +'
> +
> +test_expect_success 'clone -b two' '
> +
> +	git clone -b two parent clone-b &&
> +	(cd clone-b &&
> +	test $(git rev-parse --verify HEAD) = \
> +	     $(git rev-parse --verify refs/remotes/origin/two) &&
> +	test $(git rev-parse --verify HEAD) != \
> +	     $(git rev-parse --verify refs/remotes/origin/master))
> +
> +'
> +
> +test_expect_success 'clone -b foo' '
> +
> +	git clone -b foo parent clone-b-foo &&
> +	(cd clone-b-foo &&
> +	test $(git branch | grep \* | sed -e s:\*\ ::) = foo)

This should probably do "git symbolic-ref HEAD" instead of the branch + grep + sed. And it should also verify that rev-parse foo == rev-parse origin/foo.

And to catch the above bug, you need a second test like that, but for "master" instead of "foo".

HTH Björn

Previous: Kirill A. KorinskiyNext: Jeff King
Message 11 of 15 in “Add option -b/--branch to clone for select a new HEAD”
  1. Add option -b/--branch to clone for select a new HEADKirill A. Korinskiy, Aug 25, 2009
  2. Add option -b/--branch to clone for select a new HEADKirill A. Korinskiy, Aug 25, 2009
  3. Jeff KingAug 25, 2009
  4. Junio C HamanoAug 25, 2009
  5. Björn SteinbrinkAug 25, 2009
  6. Tor Arne VestbøAug 28, 2009
  7. Martin LanghoffAug 28, 2009
  8. Julian PhillipsAug 28, 2009
  9. Björn SteinbrinkAug 26, 2009
  10. Add option -b/--branch to clone for select a new HEADKirill A. Korinskiy, Aug 26, 2009
  11. Björn SteinbrinkAug 26, 2009
  12. Jeff KingAug 26, 2009
  13. Björn SteinbrinkAug 26, 2009
  14. Jeff KingAug 26, 2009
  15. Jeff KingAug 26, 2009

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.