Re: Local clone checks out wrong branch based on remote HEAD
On Tue, Mar 17, 2009 at 12:19:35PM -0700, Tom Preston-Werner wrote:
Show 8 quoted lines
> 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):
---
diff --git a/remote.c b/remote.c
index 76b1bbd..99d2281 100644
--- a/remote.c
+++ b/remote.c
@@ -1529,11 +1529,18 @@ struct ref *guess_remote_head(const struct ref *head,
if (head->symref)
return copy_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))
- return copy_ref(r);
+ const char *rules[] = {
+ "refs/heads/master",
+ "refs/heads/trunk",
+ };
+ int i;
+ 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))
+ return copy_ref(r);
+ }
}
/* Look for another ref that points there */