From: Tom Preston-Werner <hidden> Date: 2016-06-15 22:46:24
I'm having some unexpected behavior when cloning a remote repo that
has several branches at the same commit. On the remote side, the HEAD
is 'trunk':
git@remote ~/repositories/akincisor/site.git $ cat HEAD
ref: refs/heads/trunk
After cloning this with a standard `git clone`, the refs are:
[11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch -r -v
origin/HEAD a52528a Fixed some routing problems
origin/release a52528a Fixed some routing problems
origin/trunk a52528a Fixed some routing problems
And the checked out branch is 'release' instead of 'trunk' as I would expect:
[11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch
* release
I'm guessing that the first branch that matches the remote HEAD
revision is being checked out instead of the actual remote branch. I
would expect the correct branch to be chosen regardless of where the
branches are pointing.
Tom
--
Tom Preston-Werner
github.com/mojombo
From: Daniel Barkalow <hidden> Date: 2016-06-15 22:46:24
On Tue, 17 Mar 2009, Tom Preston-Werner wrote:
I'm having some unexpected behavior when cloning a remote repo that
has several branches at the same commit. On the remote side, the HEAD
is 'trunk':
git@remote ~/repositories/akincisor/site.git $ cat HEAD
ref: refs/heads/trunk
After cloning this with a standard `git clone`, the refs are:
[11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch -r -v
origin/HEAD a52528a Fixed some routing problems
origin/release a52528a Fixed some routing problems
origin/trunk a52528a Fixed some routing problems
And the checked out branch is 'release' instead of 'trunk' as I would expect:
[11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch
* release
I'm guessing that the first branch that matches the remote HEAD
revision is being checked out instead of the actual remote branch. I
would expect the correct branch to be chosen regardless of where the
branches are pointing.
Unfortunately, the current protocol version just sends:
a52528a HEAD
a52528a refs/heads/release
a52528a refs/heads/trunk
It doesn't transmit the fact that HEAD is a pointer to anything, or what
it's a pointer to. One thing you can do is just change your local repo to
point origin/HEAD where you want, and check out what you want; the
defaults are just to get you started. Another thing is that it will guess
"master" if there is one. I think there's also been discussion of a
protocol extension to transmit the information, although I don't know
where that ended up. (The protocol-agnostic transport infrastructure can
represent the information, but doesn't receive it for the normal protocol)
-Daniel
*This .sig left intentionally blank*
I'm guessing that the first branch that matches the remote HEAD
revision is being checked out instead of the actual remote branch. I
would expect the correct branch to be chosen regardless of where the
branches are pointing.
From: Jeff King <hidden> Date: 2016-06-15 22:46:24
On Tue, Mar 17, 2009 at 12:19:35PM -0700, Tom Preston-Werner wrote:
After cloning this with a standard `git clone`, the refs are:
[11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch -r -v
origin/HEAD a52528a Fixed some routing problems
origin/release a52528a Fixed some routing problems
origin/trunk a52528a Fixed some routing problems
And the checked out branch is 'release' instead of 'trunk' as I would expect:
As others have explained, this is because the information is lacking at
the client and we are forced to make a guess. There is a heuristic in
the guess to prefer "master" if it is an option. I suppose we could make
a similar exception for "trunk", which might make sense to people
working with SVN repositories.
OTOH, I am not sure I want to open the can of worms that is writing an
exhaustive list of heuristics that will work for everybody. Fixing the
protocol itself would probably be easier. :)
Here is what such a heuristic would look like, though (on top of next
and totally untested):
---
@@ -1529,11 +1529,18 @@ struct ref *guess_remote_head(const struct ref *head,if(head->symref)returncopy_ref(find_ref_by_name(refs,head->symref));-/* If refs/heads/master could be right, it is. */+/* We heuristically prefer certain names */if(!all){-r=find_ref_by_name(refs,"refs/heads/master");-if(r&&!hashcmp(r->old_sha1,head->old_sha1))-returncopy_ref(r);+constchar*rules[]={+"refs/heads/master",+"refs/heads/trunk",+};+inti;+for(i=0;i<ARRAY_SIZE(rules);i++){+r=find_ref_by_name(refs,rules[i]);+if(r&&!hashcmp(r->old_sha1,head->old_sha1))+returncopy_ref(r);+}}/* Look for another ref that points there */
From: Michael J Gruber <hidden> Date: 2016-06-15 22:46:24
Jeff King venit, vidit, dixit 18.03.2009 01:54:
On Tue, Mar 17, 2009 at 12:19:35PM -0700, Tom Preston-Werner wrote:
quoted
After cloning this with a standard `git clone`, the refs are:
[11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch -r -v
origin/HEAD a52528a Fixed some routing problems
origin/release a52528a Fixed some routing problems
origin/trunk a52528a Fixed some routing problems
And the checked out branch is 'release' instead of 'trunk' as I would expect:
As others have explained, this is because the information is lacking at
the client and we are forced to make a guess. There is a heuristic in
the guess to prefer "master" if it is an option. I suppose we could make
a similar exception for "trunk", which might make sense to people
working with SVN repositories.
OTOH, I am not sure I want to open the can of worms that is writing an
exhaustive list of heuristics that will work for everybody. Fixing the
protocol itself would probably be easier. :)
One might even argue that in case of ambiguities, checking out a
detached head would be most appropriate. Really, why impose creation of
certain local branches on a user at all, unless asked for? Detached
heads are natural in git! But I don't really expect positive consensus
on that one...
Michael
From: Jay Soffian <hidden> Date: 2016-06-15 22:46:25
On Wed, Mar 18, 2009 at 6:05 AM, Michael J Gruber
[off-list ref] wrote:
One might even argue that in case of ambiguities, checking out a
detached head would be most appropriate. Really, why impose creation of
certain local branches on a user at all, unless asked for? Detached
heads are natural in git! But I don't really expect positive consensus
on that one...
Shirley, you must be joking. :-)
I think there are two reasonable paths forward:
1) Address Jeff's concerns above so that the symref can be sent.
2) In lieu of (1), have clone at least warn that multiple branches
match and that it just picked one.
j.
From: Jeff King <hidden> Date: 2016-06-15 22:46:25
On Wed, Mar 18, 2009 at 05:11:25PM -0400, Jay Soffian wrote:
I think there are two reasonable paths forward:
1) Address Jeff's concerns above so that the symref can be sent.
2) In lieu of (1), have clone at least warn that multiple branches
match and that it just picked one.
I think we should do (2) regardless. Even with an updated client,
remote servers may have an older git which does not support (1) for some
time.
So I guess it's time to refactor guess_remote_head _again_. :)
-Peff
From: Jeff King <hidden> Date: 2016-06-15 22:46:25
On Wed, Mar 18, 2009 at 11:05:29AM +0100, Michael J Gruber wrote:
One might even argue that in case of ambiguities, checking out a
detached head would be most appropriate. Really, why impose creation of
certain local branches on a user at all, unless asked for? Detached
heads are natural in git! But I don't really expect positive consensus
on that one...
I'm not sure that detached HEADs are all that natural. It means that:
git clone repo-with-ambiguous-HEAD foo
cd foo
hack hack hack
git commit -a -m msg
is putting your commits "nowhere" (i.e., not on any ref). They are not
accessible for pushing, and when you checkout another branch, they will
be lost (except to the reflog).
So it clearly requires that the user be aware of what is going on, and
that they understand the subtleties of detached HEADs (something that
has caused new user confusion before, I think).
-Peff