{"thread":{"id":"18360","subject":"Local clone checks out wrong branch based on remote HEAD","startedAt":"2009-03-17T19:19:35Z","lastAt":"2009-03-19T04:04:02Z","messageCount":10,"participants":["Tom Preston-Werner","Daniel Barkalow","Nanako Shiraishi","Junio C Hamano","Jeff King","Michael J Gruber","Jay Soffian"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"108275","messageId":"b97024a40903171219k8841508p774d9dc4295a09bc@mail.gmail.com","threadId":"18360","inReplyTo":null,"subject":"Local clone checks out wrong branch based on remote HEAD","fromName":"Tom Preston-Werner","fromEmail":"tom@github.com","sentAt":"2009-03-17T19:19:35Z","receivedAt":"2009-03-17T19:19:35Z","isPatch":false,"sender":{"key":"tom@github.com","avatar":"https://gravatar.com/avatar/e38396c4b4d7977fac079a61a1b22c7eca553a9aac50efb1862daac22c65fc58?d=mp&s=160"},"body":"I'm having some unexpected behavior when cloning a remote repo that\nhas several branches at the same commit. On the remote side, the HEAD\nis 'trunk':\n\ngit@remote ~/repositories/akincisor/site.git $ cat HEAD\nref: refs/heads/trunk\n\nAfter cloning this with a standard `git clone`, the refs are:\n\n[11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch -r -v\n  origin/HEAD    a52528a Fixed some routing problems\n  origin/release a52528a Fixed some routing problems\n  origin/trunk   a52528a Fixed some routing problems\n\nAnd the checked out branch is 'release' instead of 'trunk' as I would expect:\n\n[11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch\n* release\n\nI'm guessing that the first branch that matches the remote HEAD\nrevision is being checked out instead of the actual remote branch. I\nwould expect the correct branch to be chosen regardless of where the\nbranches are pointing.\n\nTom\n\n--\nTom Preston-Werner\ngithub.com/mojombo\n"},{"id":"108276","messageId":"alpine.LNX.1.00.0903171530160.19665@iabervon.org","threadId":"18360","inReplyTo":"b97024a40903171219k8841508p774d9dc4295a09bc@mail.gmail.com","subject":"Re: Local clone checks out wrong branch based on remote HEAD","fromName":"Daniel Barkalow","fromEmail":"barkalow@iabervon.org","sentAt":"2009-03-17T19:39:55Z","receivedAt":"2009-03-17T19:39:55Z","isPatch":false,"sender":{"key":"barkalow@iabervon.org","avatar":"https://avatars.githubusercontent.com/u/55364219?v=4"},"body":"On Tue, 17 Mar 2009, Tom Preston-Werner wrote:\n\n> I'm having some unexpected behavior when cloning a remote repo that\n> has several branches at the same commit. On the remote side, the HEAD\n> is 'trunk':\n> \n> git@remote ~/repositories/akincisor/site.git $ cat HEAD\n> ref: refs/heads/trunk\n> \n> After cloning this with a standard `git clone`, the refs are:\n> \n> [11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch -r -v\n>   origin/HEAD    a52528a Fixed some routing problems\n>   origin/release a52528a Fixed some routing problems\n>   origin/trunk   a52528a Fixed some routing problems\n> \n> And the checked out branch is 'release' instead of 'trunk' as I would expect:\n> \n> [11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch\n> * release\n> \n> I'm guessing that the first branch that matches the remote HEAD\n> revision is being checked out instead of the actual remote branch. I\n> would expect the correct branch to be chosen regardless of where the\n> branches are pointing.\n\nUnfortunately, the current protocol version just sends:\n\na52528a HEAD\na52528a refs/heads/release\na52528a refs/heads/trunk\n\nIt doesn't transmit the fact that HEAD is a pointer to anything, or what \nit's a pointer to. One thing you can do is just change your local repo to \npoint origin/HEAD where you want, and check out what you want; the \ndefaults are just to get you started. Another thing is that it will guess \n\"master\" if there is one. I think there's also been discussion of a \nprotocol extension to transmit the information, although I don't know \nwhere that ended up. (The protocol-agnostic transport infrastructure can \nrepresent the information, but doesn't receive it for the normal protocol)\n\n\t-Daniel\n*This .sig left intentionally blank*\n"},{"id":"108285","messageId":"20090318063123.6117@nanako3.lavabit.com","threadId":"18360","inReplyTo":"b97024a40903171219k8841508p774d9dc4295a09bc@mail.gmail.com","subject":"Local clone checks out wrong branch based on remote HEAD","fromName":"Nanako Shiraishi","fromEmail":"nanako3@lavabit.com","sentAt":"2009-03-17T21:31:23Z","receivedAt":"2009-03-17T21:31:23Z","isPatch":false,"sender":{"key":"nanako3@lavabit.com","avatar":"https://gravatar.com/avatar/3777b9e201c5883a62b1a6fdf7c53f2d712d1d80989146063ea861e33aad72a8?d=mp&s=160"},"body":"Quoting Tom Preston-Werner <tom@github.com>:\n\n> I'm guessing that the first branch that matches the remote HEAD\n> revision is being checked out instead of the actual remote branch. I\n> would expect the correct branch to be chosen regardless of where the\n> branches are pointing.\n\nIsn't this a known issue that can be found out easily from the archive?\n\n  http://article.gmane.org/gmane.comp.version-control.git/27259\n  http://thread.gmane.org/gmane.comp.version-control.git/101956/focus=101958\n  http://thread.gmane.org/gmane.comp.version-control.git/102039\n\nIf I remember correctly, the two patch series from Junio wasn't accepted warmly and they were dropped.\n\n-- \nNanako Shiraishi\nhttp://ivory.ap.teacup.com/nanako3/\n"},{"id":"108293","messageId":"7viqm7pvkl.fsf@gitster.siamese.dyndns.org","threadId":"18360","inReplyTo":"alpine.LNX.1.00.0903171530160.19665@iabervon.org","subject":"Re: Local clone checks out wrong branch based on remote HEAD","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-03-17T23:40:26Z","receivedAt":"2009-03-17T23:40:26Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Daniel Barkalow <barkalow@iabervon.org> writes:\n\n> ... I think there's also been discussion of a \n> protocol extension to transmit the information, although I don't know \n> where that ended up.\n\nYou can find them in the list of threads posted nearby.\n\nThe first round's protocol extension was not quite backward compatible\nbut in a benign way, in that it did not break anything but induced a\nharmless warning from older ls-remote.  The second round did not have such\nflaw but it got a \"Yuck\". \n\n    From: Jeff King <peff@peff.net>\n    Date: Mon, 1 Dec 2008 12:44:15 -0500\n    Message-ID: <20081201174414.GA22185@coredump.intra.peff.net>\n    Subject: Re: [PATCH 5/6 (v2)] upload-pack: send the HEAD information\n\nI somehow feel that the \"Yuck\" was addressed not to the patches but to the\nproblem the patch needs to address.\n\nWe could resurrect it if somebody is interested.\n"},{"id":"108301","messageId":"20090318005413.GC25454@coredump.intra.peff.net","threadId":"18360","inReplyTo":"b97024a40903171219k8841508p774d9dc4295a09bc@mail.gmail.com","subject":"Re: Local clone checks out wrong branch based on remote HEAD","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-18T00:54:13Z","receivedAt":"2009-03-18T00:54:13Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Mar 17, 2009 at 12:19:35PM -0700, Tom Preston-Werner wrote:\n\n> After cloning this with a standard `git clone`, the refs are:\n> \n> [11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch -r -v\n>   origin/HEAD    a52528a Fixed some routing problems\n>   origin/release a52528a Fixed some routing problems\n>   origin/trunk   a52528a Fixed some routing problems\n> \n> And the checked out branch is 'release' instead of 'trunk' as I would expect:\n\nAs others have explained, this is because the information is lacking at\nthe client and we are forced to make a guess. There is a heuristic in\nthe guess to prefer \"master\" if it is an option. I suppose we could make\na similar exception for \"trunk\", which might make sense to people\nworking with SVN repositories.\n\nOTOH, I am not sure I want to open the can of worms that is writing an\nexhaustive list of heuristics that will work for everybody. Fixing the\nprotocol itself would probably be easier. :)\n\nHere is what such a heuristic would look like, though (on top of next\nand totally untested):\n\n---\ndiff --git a/remote.c b/remote.c\nindex 76b1bbd..99d2281 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1529,11 +1529,18 @@ struct ref *guess_remote_head(const struct ref *head,\n \tif (head->symref)\n \t\treturn copy_ref(find_ref_by_name(refs, head->symref));\n \n-\t/* If refs/heads/master could be right, it is. */\n+\t/* We heuristically prefer certain names */\n \tif (!all) {\n-\t\tr = find_ref_by_name(refs, \"refs/heads/master\");\n-\t\tif (r && !hashcmp(r->old_sha1, head->old_sha1))\n-\t\t\treturn copy_ref(r);\n+\t\tconst char *rules[] = {\n+\t\t\t\"refs/heads/master\",\n+\t\t\t\"refs/heads/trunk\",\n+\t\t};\n+\t\tint i;\n+\t\tfor (i = 0; i < ARRAY_SIZE(rules); i++) {\n+\t\t\tr = find_ref_by_name(refs, rules[i]);\n+\t\t\tif (r && !hashcmp(r->old_sha1, head->old_sha1))\n+\t\t\t\treturn copy_ref(r);\n+\t\t}\n \t}\n \n \t/* Look for another ref that points there */\n"},{"id":"108323","messageId":"20090318015158.GA32119@coredump.intra.peff.net","threadId":"18360","inReplyTo":"7viqm7pvkl.fsf@gitster.siamese.dyndns.org","subject":"Re: Local clone checks out wrong branch based on remote HEAD","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-18T01:51:58Z","receivedAt":"2009-03-18T01:51:58Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Mar 17, 2009 at 04:40:26PM -0700, Junio C Hamano wrote:\n\n> The first round's protocol extension was not quite backward compatible\n> but in a benign way, in that it did not break anything but induced a\n> harmless warning from older ls-remote.  The second round did not have such\n> flaw but it got a \"Yuck\". \n> \n>     From: Jeff King <peff@peff.net>\n>     Date: Mon, 1 Dec 2008 12:44:15 -0500\n>     Message-ID: <20081201174414.GA22185@coredump.intra.peff.net>\n>     Subject: Re: [PATCH 5/6 (v2)] upload-pack: send the HEAD information\n> \n> I somehow feel that the \"Yuck\" was addressed not to the patches but to the\n> problem the patch needs to address.\n\nActually, you addressed my original \"yuck\" as it was a misunderstanding\non my part of how the protocol worked. I did lay out a few further\ncomplaints in:\n\n  http://thread.gmane.org/gmane.comp.version-control.git/102039/focus=102070\n\nTo summarize, they were:\n\n  1. sending the server capabilities repeatedly\n\n  2. extensibility of this technique\n\n  3. handling empty clone\n\nI think (1) is something we can just live with. It's a few dozen extra\nbytes per symref line. But just look at all the crap a normal HTTP\nrequest sends. ;)\n\nFor (2), I think it would work to simply define each NUL-separated field\nafter the first as an \"extra info\" slot, and put a header in that slot.\nSo send something like:\n\n  [0-9a-f]{40} HEAD\\0<server capabilities>\\0symref refs/heads/master\\n\n\nAnd as we add new \"here is something extra about this ref\" fields, they\nget assigned new headers. Sadly it is too late to do such a thing for\nthe server capabilities slot, so slot 1 must remain there. But at least\nwe can keep it open for the future.\n\nFor (3), we would have to investigate how badly a 0{40} sha-1 break\ncurrent clients (which understand empty clone, but maybe not this new\n\"branch to be born\" syntax). Or maybe it is OK to say \"this is the new\nway to do empty clone, and everything less than v1.6.3 will not be able\nto handle your empty clone\" (which is true for everything less than\nv1.6.2 or so, anyway).\n\n-Peff\n"},{"id":"108361","messageId":"49C0C769.8020401@drmicha.warpmail.net","threadId":"18360","inReplyTo":"20090318005413.GC25454@coredump.intra.peff.net","subject":"Re: Local clone checks out wrong branch based on remote HEAD","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2009-03-18T10:05:29Z","receivedAt":"2009-03-18T10:05:29Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Jeff King venit, vidit, dixit 18.03.2009 01:54:\n> On Tue, Mar 17, 2009 at 12:19:35PM -0700, Tom Preston-Werner wrote:\n> \n>> After cloning this with a standard `git clone`, the refs are:\n>>\n>> [11:48][tom@solid:~/dev/sandbox/site(release)]$ git branch -r -v\n>>   origin/HEAD    a52528a Fixed some routing problems\n>>   origin/release a52528a Fixed some routing problems\n>>   origin/trunk   a52528a Fixed some routing problems\n>>\n>> And the checked out branch is 'release' instead of 'trunk' as I would expect:\n> \n> As others have explained, this is because the information is lacking at\n> the client and we are forced to make a guess. There is a heuristic in\n> the guess to prefer \"master\" if it is an option. I suppose we could make\n> a similar exception for \"trunk\", which might make sense to people\n> working with SVN repositories.\n> \n> OTOH, I am not sure I want to open the can of worms that is writing an\n> exhaustive list of heuristics that will work for everybody. Fixing the\n> protocol itself would probably be easier. :)\n\nOne might even argue that in case of ambiguities, checking out a\ndetached head would be most appropriate. Really, why impose creation of\ncertain local branches on a user at all, unless asked for? Detached\nheads are natural in git! But I don't really expect positive consensus\non that one...\n\nMichael\n"},{"id":"108424","messageId":"76718490903181411p743382f1qb053363f28a800b1@mail.gmail.com","threadId":"18360","inReplyTo":"49C0C769.8020401@drmicha.warpmail.net","subject":"Re: Local clone checks out wrong branch based on remote HEAD","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2009-03-18T21:11:25Z","receivedAt":"2009-03-18T21:11:25Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Wed, Mar 18, 2009 at 6:05 AM, Michael J Gruber\n<git@drmicha.warpmail.net> wrote:\n> One might even argue that in case of ambiguities, checking out a\n> detached head would be most appropriate. Really, why impose creation of\n> certain local branches on a user at all, unless asked for? Detached\n> heads are natural in git! But I don't really expect positive consensus\n> on that one...\n\nShirley, you must be joking. :-)\n\nI think there are two reasonable paths forward:\n\n1) Address Jeff's concerns above so that the symref can be sent.\n2) In lieu of (1), have clone at least warn that multiple branches\nmatch and that it just picked one.\n\nj.\n"},{"id":"108468","messageId":"20090319040229.GA32435@coredump.intra.peff.net","threadId":"18360","inReplyTo":"49C0C769.8020401@drmicha.warpmail.net","subject":"Re: Local clone checks out wrong branch based on remote HEAD","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-19T04:02:29Z","receivedAt":"2009-03-19T04:02:29Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Mar 18, 2009 at 11:05:29AM +0100, Michael J Gruber wrote:\n\n> One might even argue that in case of ambiguities, checking out a\n> detached head would be most appropriate. Really, why impose creation of\n> certain local branches on a user at all, unless asked for? Detached\n> heads are natural in git! But I don't really expect positive consensus\n> on that one...\n\nI'm not sure that detached HEADs are all that natural. It means that:\n\n  git clone repo-with-ambiguous-HEAD foo\n  cd foo\n  hack hack hack\n  git commit -a -m msg\n\nis putting your commits \"nowhere\" (i.e., not on any ref). They are not\naccessible for pushing, and when you checkout another branch, they will\nbe lost (except to the reflog).\n\nSo it clearly requires that the user be aware of what is going on, and\nthat they understand the subtleties of detached HEADs (something that\nhas caused new user confusion before, I think).\n\n-Peff\n"},{"id":"108467","messageId":"20090319040402.GB32435@coredump.intra.peff.net","threadId":"18360","inReplyTo":"76718490903181411p743382f1qb053363f28a800b1@mail.gmail.com","subject":"Re: Local clone checks out wrong branch based on remote HEAD","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-03-19T04:04:02Z","receivedAt":"2009-03-19T04:04:02Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Mar 18, 2009 at 05:11:25PM -0400, Jay Soffian wrote:\n\n> I think there are two reasonable paths forward:\n> \n> 1) Address Jeff's concerns above so that the symref can be sent.\n> 2) In lieu of (1), have clone at least warn that multiple branches\n> match and that it just picked one.\n\nI think we should do (2) regardless. Even with an updated client,\nremote servers may have an older git which does not support (1) for some\ntime.\n\nSo I guess it's time to refactor guess_remote_head _again_. :)\n\n-Peff\n"}]}