{"thread":{"id":"22441","subject":"master^ is not a local branch -- huh?!?","startedAt":"2010-01-29T20:20:46Z","lastAt":"2010-01-31T07:32:22Z","messageCount":94,"participants":["Ron1","Jacob Helwig","Johannes Schindelin","Sverre Rabbelier","Octavio Alvarez","Scott R. Godin","Junio C Hamano","Nicolas Pitre","Ron Garret","A Large Angry SCM","Julian Phillips","Michael Witten","Mark Lodato","Jay Soffian","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"132985","messageId":"ron1-2E17EF.12204629012010@news.gmane.org","threadId":"22441","inReplyTo":null,"subject":"master^ is not a local branch -- huh?!?","fromName":"Ron1","fromEmail":"ron1@flownet.com","sentAt":"2010-01-29T20:20:46Z","receivedAt":"2010-01-29T20:20:46Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"[ron@mickey]$ git checkout master\nAlready on 'master'\n[ron@mickey]$ git checkout master^\nNote: moving to 'master^' which isn't a local branch\nIf you want to create a new branch from this checkout, you may do so\n(now or later) by using -b with the checkout command again. Example:\n  git checkout -b <new_branch_name>\nHEAD is now at 7be05e0... test\n[ron@mickey]$ git branch\n* (no branch)\n  master\n[ron@mickey]$\n\nHuh?!?\n\nThis is a test repository which has never been pulled from nor pushed to \nanywhere.  So how is it possible that I have a non-local branch?\n\nThanks,\nrg\n"},{"id":"132986","messageId":"8c9a061001291227v34ca0745l1ab35ef6ca5863dc@mail.gmail.com","threadId":"22441","inReplyTo":"ron1-2E17EF.12204629012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Jacob Helwig","fromEmail":"jacob.helwig@gmail.com","sentAt":"2010-01-29T20:27:56Z","receivedAt":"2010-01-29T20:27:56Z","isPatch":false,"sender":{"key":"jacob.helwig@gmail.com","avatar":"https://avatars.githubusercontent.com/u/14557?v=4"},"body":"On Fri, Jan 29, 2010 at 12:20, Ron1 <ron1@flownet.com> wrote:\n> [ron@mickey]$ git checkout master\n> Already on 'master'\n> [ron@mickey]$ git checkout master^\n> Note: moving to 'master^' which isn't a local branch\n> If you want to create a new branch from this checkout, you may do so\n> (now or later) by using -b with the checkout command again. Example:\n>  git checkout -b <new_branch_name>\n> HEAD is now at 7be05e0... test\n> [ron@mickey]$ git branch\n> * (no branch)\n>  master\n> [ron@mickey]$\n>\n> Huh?!?\n>\n> This is a test repository which has never been pulled from nor pushed to\n> anywhere.  So how is it possible that I have a non-local branch?\n>\n> Thanks,\n> rg\n>\n\nmaster^ is a commit (the first parent of master), not a branch (local\nor otherwise).\n"},{"id":"132990","messageId":"op.u7a909hf4oyyg1@alvarezp-ws","threadId":"22441","inReplyTo":"ron1-2E17EF.12204629012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Octavio Alvarez","fromEmail":"alvarezp@alvarezp.ods.org","sentAt":"2010-01-29T20:32:59Z","receivedAt":"2010-01-29T20:32:59Z","isPatch":false,"sender":{"key":"alvarezp@alvarezp.ods.org","avatar":null},"body":"On Fri, 29 Jan 2010 12:20:46 -0800, Ron1 <ron1@flownet.com> wrote:\n\n> [ron@mickey]$ git checkout master\n> Already on 'master'\n> [ron@mickey]$ git checkout master^\n> Note: moving to 'master^' which isn't a local branch\n> If you want to create a new branch from this checkout, you may do so\n> (now or later) by using -b with the checkout command again. Example:\n>   git checkout -b <new_branch_name>\n> HEAD is now at 7be05e0... test\n> [ron@mickey]$ git branch\n> * (no branch)\n>   master\n> [ron@mickey]$\n>\n> Huh?!?\n>\n> This is a test repository which has never been pulled from nor pushed to\n> anywhere.  So how is it possible that I have a non-local branch?\n\n\"Is a non-local branch\" is not the same as \"is not a local branch\".\n\nThink \"branches\" as tags that advance when you commit over them.\n\nIf you do gitk --all, only those commits with a green tag are\n\"branches\".\n\nIt means that if you switch to master^ and commit, your commit will\nbe applied but not tracked (since there is not any branch to advance).\n\nYou would need to do git checkout -b 'new_branch', and then commit.\nNow, new_branch will advance with your new commit.\n"},{"id":"132989","messageId":"fabb9a1e1001291235h26681e65qe4851cae1c536b6d@mail.gmail.com","threadId":"22441","inReplyTo":"8c9a061001291227v34ca0745l1ab35ef6ca5863dc@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-01-29T20:35:08Z","receivedAt":"2010-01-29T20:35:08Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Jan 29, 2010 at 21:27, Jacob Helwig <jacob.helwig@gmail.com> wrote:\n> On Fri, Jan 29, 2010 at 12:20, Ron1 <ron1@flownet.com> wrote:\n>> This is a test repository which has never been pulled from nor pushed to\n>> anywhere.  So how is it possible that I have a non-local branch?\n>\n> master^ is a commit (the first parent of master), not a branch (local\n> or otherwise).\n\nPerhaps we should change the message to say \"not a branch\" if it's not\na reference to a remote branch? Or simply changing the text to \"not a\n(local) branch\"?\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"132988","messageId":"alpine.DEB.1.00.1001292131330.3749@intel-tinevez-2-302","threadId":"22441","inReplyTo":"8c9a061001291227v34ca0745l1ab35ef6ca5863dc@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-01-29T20:35:12Z","receivedAt":"2010-01-29T20:35:12Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 29 Jan 2010, Jacob Helwig wrote:\n\n> On Fri, Jan 29, 2010 at 12:20, Ron1 <ron1@flownet.com> wrote:\n> > [ron@mickey]$ git checkout master\n> > Already on 'master'\n> > [ron@mickey]$ git checkout master^\n> > Note: moving to 'master^' which isn't a local branch\n> > If you want to create a new branch from this checkout, you may do so\n> > (now or later) by using -b with the checkout command again. Example:\n> >  git checkout -b <new_branch_name>\n> > HEAD is now at 7be05e0... test\n> > [ron@mickey]$ git branch\n> > * (no branch)\n> >  master\n> > [ron@mickey]$\n> >\n> > Huh?!?\n> >\n> > This is a test repository which has never been pulled from nor pushed to\n> > anywhere.  So how is it possible that I have a non-local branch?\n> \n> master^ is a commit (the first parent of master), not a branch (local\n> or otherwise).\n\nIndeed.  Maybe you (Ron1) need to get a bit more acquainted to Git before \ncomplaining.\n\nGit is not user-friendly (much to my chagrin, and I tried to change it, \nbut it is not going to happen), so the only way out is to really read up \non good tutorials/manuals before you complain about something that is not \nworking as you expect it.\n\nJust as a general hint, I think the best documentation about Git was \nwritten by J. Bruce Fields (the user manual) and Scott Chacon (everything \nthat has GitHub written on it, and Git Pro, and much, much more).  If you \nhappen to speak Japanese, Junio's book might help you understand the ideas \nbehind the current Git user interface, too.\n\nHth,\nDscho\n"},{"id":"132992","messageId":"hjvgs1$rep$1@ger.gmane.org","threadId":"22441","inReplyTo":"ron1-2E17EF.12204629012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Scott R. Godin","fromEmail":"scottg.wp-hackers@mhg2.com","sentAt":"2010-01-29T20:36:18Z","receivedAt":"2010-01-29T20:36:18Z","isPatch":false,"sender":{"key":"scottg.wp-hackers@mhg2.com","avatar":"https://gravatar.com/avatar/766980733f46a32860153479ca94372e4fff5c4632e8586dbbfb143051d231ce?d=mp&s=160"},"body":"On 01/29/2010 03:20 PM, Ron1 wrote:\n> [ron@mickey]$ git checkout master\n> Already on 'master'\n> [ron@mickey]$ git checkout master^\n> Note: moving to 'master^' which isn't a local branch\n> If you want to create a new branch from this checkout, you may do so\n> (now or later) by using -b with the checkout command again. Example:\n>    git checkout -b<new_branch_name>\n> HEAD is now at 7be05e0... test\n> [ron@mickey]$ git branch\n> * (no branch)\n>    master\n> [ron@mickey]$\n>\n> Huh?!?\n>\n> This is a test repository which has never been pulled from nor pushed to\n> anywhere.  So how is it possible that I have a non-local branch?\n>\n> Thanks,\n> rg\n>\n\nI believe what you're seeing is known as a detached head (see \n<http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html> \nthough I could be wrong about this.)\n\nI think you may have intended to do git checkout HEAD^ or something \nsimilar? basically what you did was (I think) checkout (or attempt to \ncheckout) the parent commit on master.\n\nthis may offer some additional food for thought: \n<http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html#_exploring_history>\n\n-- \n(please respond to the list as opposed to my email box directly,\nunless you are supplying private information you don't want public\non the list)\n"},{"id":"132991","messageId":"8c9a061001291238o77040252s36d8a88a546d014a@mail.gmail.com","threadId":"22441","inReplyTo":"fabb9a1e1001291235h26681e65qe4851cae1c536b6d@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Jacob Helwig","fromEmail":"jacob.helwig@gmail.com","sentAt":"2010-01-29T20:38:13Z","receivedAt":"2010-01-29T20:38:13Z","isPatch":false,"sender":{"key":"jacob.helwig@gmail.com","avatar":"https://avatars.githubusercontent.com/u/14557?v=4"},"body":"On Fri, Jan 29, 2010 at 12:35, Sverre Rabbelier <srabbelier@gmail.com> wrote:\n> Heya,\n>\n> On Fri, Jan 29, 2010 at 21:27, Jacob Helwig <jacob.helwig@gmail.com> wrote:\n>> On Fri, Jan 29, 2010 at 12:20, Ron1 <ron1@flownet.com> wrote:\n>>> This is a test repository which has never been pulled from nor pushed to\n>>> anywhere.  So how is it possible that I have a non-local branch?\n>>\n>> master^ is a commit (the first parent of master), not a branch (local\n>> or otherwise).\n>\n> Perhaps we should change the message to say \"not a branch\" if it's not\n> a reference to a remote branch? Or simply changing the text to \"not a\n> (local) branch\"?\n>\n\nI think \"not a branch\" would be better than \"not a (local) branch\".\nIn my mind, the latter reads almost exactly the same as the current\nmessage.\n"},{"id":"132993","messageId":"7veil8iqnj.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"fabb9a1e1001291235h26681e65qe4851cae1c536b6d@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T20:48:16Z","receivedAt":"2010-01-29T20:48:16Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sverre Rabbelier <srabbelier@gmail.com> writes:\n\n>> master^ is a commit (the first parent of master), not a branch (local\n>> or otherwise).\n>\n> Perhaps we should change the message to say \"not a branch\" if it's not\n> a reference to a remote branch? Or simply changing the text to \"not a\n> (local) branch\"?\n\nI think \"not a branch\" is a good suggestion, whether the target of\ncheckout is \"master^\" or \"origin/topic\".\n\nThese days, you can say \"git checkout topic\" to automagically create a\nlocal \"topic\" branch that forks from \"origin/topic\" remote tracking branch\nwhen you have one, thanks to Dscho's UI improvement ideas (one less\nreason you may end up on a detached HEAD state without wanting to).\n"},{"id":"132994","messageId":"fabb9a1e1001291256j71e2c95cic21cb5a6a0cc1fe8@mail.gmail.com","threadId":"22441","inReplyTo":"7veil8iqnj.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-01-29T20:56:30Z","receivedAt":"2010-01-29T20:56:30Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Jan 29, 2010 at 21:48, Junio C Hamano <gitster@pobox.com> wrote:\n> I think \"not a branch\" is a good suggestion, whether the target of\n> checkout is \"master^\" or \"origin/topic\".\n\nMhhh, for added clarity, do we want to change it to \"branch name\"? Since ...\n\n$ git grep \"branch name\" Documentation/ | wc -l\n58\n\n... suggests that we use that in other places as well?\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"132997","messageId":"1264799342-11093-1-git-send-email-srabbelier@gmail.com","threadId":"22441","inReplyTo":"fabb9a1e1001291256j71e2c95cic21cb5a6a0cc1fe8@mail.gmail.com","subject":"[PATCH] checkout: warn about 'branch name' rather than 'local branch'","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-01-29T21:09:02Z","receivedAt":"2010-01-29T21:09:02Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"These days, you can say \"git checkout topic\" to automagically create\na local \"topic\" branch that forks from \"origin/topic\" remote tracking\nbranch when you have one, thanks to Dscho's UI improvement ideas. As\nsuch it is more appropriate to say that the user is checking out\nsomething that is not a branch name, rather than saying it is not a\n'local branch'.\n\nSigned-off-by: Sverre Rabbelier <srabbelier@gmail.com>\n---\n\n  Junio, I used part of your reply as the commit message, is that ok?\n\n  Only change is s/local branch/branch name/.\n\n builtin-checkout.c |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 5277817..4b34314 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -523,7 +523,7 @@ static void update_refs_for_switch(struct checkout_opts *opts,\n \t\t\t   REF_NODEREF, DIE_ON_ERR);\n \t\tif (!opts->quiet) {\n \t\t\tif (old->path)\n-\t\t\t\tfprintf(stderr, \"Note: moving to '%s' which isn't a local branch\\nIf you want to create a new branch from this checkout, you may do so\\n(now or later) by using -b with the checkout command again. Example:\\n  git checkout -b <new_branch_name>\\n\", new->name);\n+\t\t\t\tfprintf(stderr, \"Note: moving to '%s' which isn't a branch name\\nIf you want to create a new branch from this checkout, you may do so\\n(now or later) by using -b with the checkout command again. Example:\\n  git checkout -b <new_branch_name>\\n\", new->name);\n \t\t\tdescribe_detached_head(\"HEAD is now at\", new->commit);\n \t\t}\n \t}\n-- \n1.6.6.rc1.56.gaea25.dirty\n"},{"id":"132996","messageId":"ron1-F6943B.13162129012010@news.gmane.org","threadId":"22441","inReplyTo":"alpine.DEB.1.00.1001292131330.3749@intel-tinevez-2-302","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron1","fromEmail":"ron1@flownet.com","sentAt":"2010-01-29T21:16:21Z","receivedAt":"2010-01-29T21:16:21Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <alpine.DEB.1.00.1001292131330.3749@intel-tinevez-2-302>,\n Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:\n\n> Hi,\n> \n> On Fri, 29 Jan 2010, Jacob Helwig wrote:\n> \n> > On Fri, Jan 29, 2010 at 12:20, Ron1 <ron1@flownet.com> wrote:\n> > > [ron@mickey]$ git checkout master\n> > > Already on 'master'\n> > > [ron@mickey]$ git checkout master^\n> > > Note: moving to 'master^' which isn't a local branch\n> > > If you want to create a new branch from this checkout, you may do so\n> > > (now or later) by using -b with the checkout command again. Example:\n> > >  git checkout -b <new_branch_name>\n> > > HEAD is now at 7be05e0... test\n> > > [ron@mickey]$ git branch\n> > > * (no branch)\n> > >  master\n> > > [ron@mickey]$\n> > >\n> > > Huh?!?\n> > >\n> > > This is a test repository which has never been pulled from nor pushed to\n> > > anywhere.  So how is it possible that I have a non-local branch?\n> > \n> > master^ is a commit (the first parent of master), not a branch (local\n> > or otherwise).\n> \n> Indeed.  Maybe you (Ron1) need to get a bit more acquainted to Git before \n> complaining.\n\n\nChill, dude.  I'm not complaining.  I'm just confused.\n\nI know that master^ is a commit and not a branch.  I thought I was \ninvoking the third variant of git-checkout (as given on the git-checkout \nman page) and checking out a commit (which the man page calls a \ntree-ish).\n\nIn any case, since my question seems to have sparked some discussion, \nI'd like to offer two observations:\n\n1.  Saying \"isn't a local branch\" is mightily confusing, because it is \nambiguous whether the problem is that it isn't a branch or if it isn't \nlocal.\n\n2.  If I pass something to git checkout (or any other command for that \nmatter) that it expects to be a branch but isn't a branch it would be \nmuch better if it just gave an error and did nothing rather than give a \n(confusing) warning and try to extrapolate the user's intentions.  \nWhatever a user could possibly mean by 'git checkout master^' it is \nalmost certainly not what that command actually does at the moment.\n\nrg\n"},{"id":"132998","messageId":"1264799942-4531-1-git-send-email-jacob.helwig@gmail.com","threadId":"22441","inReplyTo":"1264799342-11093-1-git-send-email-srabbelier@gmail.com","subject":"[PATCH] checkout: Fix test for s/local branch/branch name/ change.","fromName":"Jacob Helwig","fromEmail":"jacob.helwig@gmail.com","sentAt":"2010-01-29T21:19:02Z","receivedAt":"2010-01-29T21:19:02Z","isPatch":true,"sender":{"key":"jacob.helwig@gmail.com","avatar":"https://avatars.githubusercontent.com/u/14557?v=4"},"body":"Signed-off-by: Jacob Helwig <jacob.helwig@gmail.com>\n---\n\nThis should probably be squashed into Sverre Rabbelier's change, if this is\ndecided as the way to go.\n\n t/t7201-co.sh |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/t/t7201-co.sh b/t/t7201-co.sh\nindex 6442f71..b6e3216 100755\n--- a/t/t7201-co.sh\n+++ b/t/t7201-co.sh\n@@ -171,7 +171,7 @@ test_expect_success 'checkout to detach HEAD' '\n \tgit checkout -f renamer && git clean -f &&\n \tgit checkout renamer^ 2>messages &&\n \t(cat >messages.expect <<EOF\n-Note: moving to '\\''renamer^'\\'' which isn'\\''t a local branch\n+Note: moving to '\\''renamer^'\\'' which isn'\\''t a branch name\n If you want to create a new branch from this checkout, you may do so\n (now or later) by using -b with the checkout command again. Example:\n   git checkout -b <new_branch_name>\n-- \n1.6.6.1\n"},{"id":"133000","messageId":"fabb9a1e1001291320s25e237bdidf40e4b8a432e7b5@mail.gmail.com","threadId":"22441","inReplyTo":"1264799942-4531-1-git-send-email-jacob.helwig@gmail.com","subject":"Re: [PATCH] checkout: Fix test for s/local branch/branch name/ change.","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-01-29T21:20:32Z","receivedAt":"2010-01-29T21:20:32Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Jan 29, 2010 at 22:19, Jacob Helwig <jacob.helwig@gmail.com> wrote:\n> This should probably be squashed into Sverre Rabbelier's change, if this is\n> decided as the way to go.\n\nAh, excellent point, apologies :(. I saw it show up when I grepped for\nthe message, not sure why I didn't do anything with that.\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"132999","messageId":"alpine.LFD.2.00.1001291614550.1681@xanadu.home","threadId":"22441","inReplyTo":"7veil8iqnj.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-29T21:20:38Z","receivedAt":"2010-01-29T21:20:38Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Junio C Hamano wrote:\n\n> Sverre Rabbelier <srabbelier@gmail.com> writes:\n> \n> >> master^ is a commit (the first parent of master), not a branch (local\n> >> or otherwise).\n> >\n> > Perhaps we should change the message to say \"not a branch\" if it's not\n> > a reference to a remote branch? Or simply changing the text to \"not a\n> > (local) branch\"?\n> \n> I think \"not a branch\" is a good suggestion, whether the target of\n> checkout is \"master^\" or \"origin/topic\".\n> \n> These days, you can say \"git checkout topic\" to automagically create a\n> local \"topic\" branch that forks from \"origin/topic\" remote tracking branch\n> when you have one, thanks to Dscho's UI improvement ideas (one less\n> reason you may end up on a detached HEAD state without wanting to).\n\nIf this is the case then I'm really disappointed.\n\nWith all due respects, I don't share Dscho's sentiment about Git's \nalleged non user-friendliness.  And I always praised Git's ability to \nuse a detached head to check out a remote branch, and never had any \nproblem teaching this concept to people.  So the above is not a UI \nimprovement at all to me.\n\n\nNicolas\n"},{"id":"133001","messageId":"fabb9a1e1001291321v708c7cb4sec8e944f336d04fd@mail.gmail.com","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001291614550.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-01-29T21:21:55Z","receivedAt":"2010-01-29T21:21:55Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Jan 29, 2010 at 22:20, Nicolas Pitre <nico@fluxnic.net> wrote:\n> With all due respects, I don't share Dscho's sentiment about Git's\n> alleged non user-friendliness.  And I always praised Git's ability to\n> use a detached head to check out a remote branch, and never had any\n> problem teaching this concept to people.  So the above is not a UI\n> improvement at all to me.\n\nI think 'git checkout origin/master^0' still works?\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"133002","messageId":"ron1-953427.13240429012010@news.gmane.org","threadId":"22441","inReplyTo":"hjvgs1$rep$1@ger.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-29T21:24:04Z","receivedAt":"2010-01-29T21:24:04Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <hjvgs1$rep$1@ger.gmane.org>,\n \"Scott R. Godin\" <scottg.wp-hackers@mhg2.com> wrote:\n\n> On 01/29/2010 03:20 PM, Ron1 wrote:\n> > [ron@mickey]$ git checkout master\n> > Already on 'master'\n> > [ron@mickey]$ git checkout master^\n> > Note: moving to 'master^' which isn't a local branch\n> > If you want to create a new branch from this checkout, you may do so\n> > (now or later) by using -b with the checkout command again. Example:\n> >    git checkout -b<new_branch_name>\n> > HEAD is now at 7be05e0... test\n> > [ron@mickey]$ git branch\n> > * (no branch)\n> >    master\n> > [ron@mickey]$\n> >\n> > Huh?!?\n> >\n> > This is a test repository which has never been pulled from nor pushed to\n> > anywhere.  So how is it possible that I have a non-local branch?\n> >\n> > Thanks,\n> > rg\n> >\n> \n> I believe what you're seeing is known as a detached head (see \n> <http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html> \n> though I could be wrong about this.)\n> \n> I think you may have intended to do git checkout HEAD^ or something \n> similar?\n\nYes, in fact that is exactly what I am trying to do.  But that has the \nsame result.\n\n> basically what you did was (I think) checkout (or attempt to \n> checkout) the parent commit on master.\n\nYes.  I posted it that way simply because 'git commit HEAD' depends on \nwhat HEAD is.  If HEAD is the head of master (which it was) then the \nresult is the same.\n\n> \n> this may offer some additional food for thought: \n> <http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html#_exploring_h\n> istory>\n\nYes, I read that.  But what I'm trying to do is not just *look* at the \nhistory, I want to restore my working tree to a previous version.  The \n\"Exploring History\" section of the docs doesn't say how to do that.\n\nrg\n"},{"id":"133003","messageId":"8c9a061001291325i4b8898b9m46054040c69f8fc6@mail.gmail.com","threadId":"22441","inReplyTo":"ron1-F6943B.13162129012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Jacob Helwig","fromEmail":"jacob.helwig@gmail.com","sentAt":"2010-01-29T21:25:18Z","receivedAt":"2010-01-29T21:25:18Z","isPatch":false,"sender":{"key":"jacob.helwig@gmail.com","avatar":"https://avatars.githubusercontent.com/u/14557?v=4"},"body":"On Fri, Jan 29, 2010 at 13:16, Ron1 <ron1@flownet.com> wrote:\n> I know that master^ is a commit and not a branch.  I thought I was\n> invoking the third variant of git-checkout (as given on the git-checkout\n> man page) and checking out a commit (which the man page calls a\n> tree-ish).\n>\n> In any case, since my question seems to have sparked some discussion,\n> I'd like to offer two observations:\n>\n> 1.  Saying \"isn't a local branch\" is mightily confusing, because it is\n> ambiguous whether the problem is that it isn't a branch or if it isn't\n> local.\n>\n> 2.  If I pass something to git checkout (or any other command for that\n> matter) that it expects to be a branch but isn't a branch it would be\n> much better if it just gave an error and did nothing rather than give a\n> (confusing) warning and try to extrapolate the user's intentions.\n> Whatever a user could possibly mean by 'git checkout master^' it is\n> almost certainly not what that command actually does at the moment.\n>\n\nI don't think that #2 would be possible.  My understanding is that\nbranches are basically just there as convenient \"names\" for arbitrary\ncommits.  In other words (in my understanding): There is no place that\nexpects a \"branch\" where a commit (SHA-1) would not work (and be a\nperfectly valid use).\n"},{"id":"133004","messageId":"fabb9a1e1001291328s1df443d6jdf0501cda17072de@mail.gmail.com","threadId":"22441","inReplyTo":"ron1-953427.13240429012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-01-29T21:28:57Z","receivedAt":"2010-01-29T21:28:57Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Jan 29, 2010 at 22:24, Ron Garret <ron1@flownet.com> wrote:\n> Yes, I read that.  But what I'm trying to do is not just *look* at the\n> history, I want to restore my working tree to a previous version.  The\n> \"Exploring History\" section of the docs doesn't say how to do that.\n\nDo you want to restore your working tree only, or also throw away the\nhistory? If the former, you could look at 'git revert', if the latter,\n'git reset --hard' could be what you need (warning: the latter is a\ndestructive command that will let you _throw away history_).\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"133005","messageId":"alpine.LFD.2.00.1001291628510.1681@xanadu.home","threadId":"22441","inReplyTo":"fabb9a1e1001291321v708c7cb4sec8e944f336d04fd@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-29T21:29:40Z","receivedAt":"2010-01-29T21:29:40Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Sverre Rabbelier wrote:\n\n> Heya,\n> \n> On Fri, Jan 29, 2010 at 22:20, Nicolas Pitre <nico@fluxnic.net> wrote:\n> > With all due respects, I don't share Dscho's sentiment about Git's\n> > alleged non user-friendliness.  And I always praised Git's ability to\n> > use a detached head to check out a remote branch, and never had any\n> > problem teaching this concept to people.  So the above is not a UI\n> > improvement at all to me.\n> \n> I think 'git checkout origin/master^0' still works?\n\nThen who was arguing about making Git more user friendly rather \nthen less?\n\n\nNicolas\n"},{"id":"133006","messageId":"fabb9a1e1001291332w1d161f8at58aa6fe6908bd77f@mail.gmail.com","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001291628510.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-01-29T21:32:41Z","receivedAt":"2010-01-29T21:32:41Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Jan 29, 2010 at 22:29, Nicolas Pitre <nico@fluxnic.net> wrote:\n> Then who was arguing about making Git more user friendly rather\n> then less?\n\nUsing a detached head is a more advanced feature than wanting to\ncheckout a remote branch locally, creating a local tracking branch. As\nsuch, 'git checkout origin/topic' now means the same as 'git checkout\n-t origin/topic', and you can get the old behavior back by doing 'git\ncheckout origin/topic^0'. I don't see what the problem is, if you're\nusing a detached head you're an advanced enough git user that you can\nremember that you can use '^0' to detach your head. It's not all that\nuncommon to do 'git checkout HEAD^0' to detach your head to the\ncurrent branch, no?\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"133007","messageId":"ron1-1F1799.13340029012010@news.gmane.org","threadId":"22441","inReplyTo":"op.u7a909hf4oyyg1@alvarezp-ws","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-29T21:34:01Z","receivedAt":"2010-01-29T21:34:01Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <op.u7a909hf4oyyg1@alvarezp-ws>,\n \"Octavio Alvarez\" <alvarezp@alvarezp.ods.org> wrote:\n\n> On Fri, 29 Jan 2010 12:20:46 -0800, Ron1 <ron1@flownet.com> wrote:\n> \n> > [ron@mickey]$ git checkout master\n> > Already on 'master'\n> > [ron@mickey]$ git checkout master^\n> > Note: moving to 'master^' which isn't a local branch\n> > If you want to create a new branch from this checkout, you may do so\n> > (now or later) by using -b with the checkout command again. Example:\n> >   git checkout -b <new_branch_name>\n> > HEAD is now at 7be05e0... test\n> > [ron@mickey]$ git branch\n> > * (no branch)\n> >   master\n> > [ron@mickey]$\n> >\n> > Huh?!?\n> >\n> > This is a test repository which has never been pulled from nor pushed to\n> > anywhere.  So how is it possible that I have a non-local branch?\n> \n> \"Is a non-local branch\" is not the same as \"is not a local branch\".\n> \n> Think \"branches\" as tags that advance when you commit over them.\n> \n> If you do gitk --all, only those commits with a green tag are\n> \"branches\".\n> \n> It means that if you switch to master^ and commit, your commit will\n> be applied but not tracked (since there is not any branch to advance).\n> \n> You would need to do git checkout -b 'new_branch', and then commit.\n> Now, new_branch will advance with your new commit.\n\nOK, I think I understand that.\n\nHere's the thing: I can do this:\n\ngit checkout commit-id filename\n\nand restore a particular revision of a particular file to my working \ntree without affecting my HEAD pointer.  I would expect then that\n\ngit checkout commit-id\n\nwith no filename would do the same thing, except restore the entire tree \nfrom that commit (including deleting files that didnt' exist then).  And \nindeed it does that (or at least appears to -- I haven't explored this \nin depth), except that it DOES move my HEAD pointer to this weird \nnon-branch thing.\n\nHere's what I think would be the correct behavior:\n\n\n\n[ron@mickey]$ git checkout master^\n\n\"WARNING: master^ is not a branch.  It is a commit on the master branch.\nSince the the commit you are asking for is on the same branch as your\ncurrent HEAD pointer, here's what I'm going to do:\n\n1.  Copy the master^ commit to your working tree\n2.  Leave your HEAD pointer where is was (i.e. pointing to the head\nof the master branch).\n\nIf this is not what you wanted, you can undo it by typing \"git checkout \nHEAD\".  Also, in the future, you can avoid this warning by typing ...\ninstead.\n\n\n\nOr something like that.\n\nrg\n"},{"id":"133008","messageId":"7vzl3wh9wx.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"fabb9a1e1001291256j71e2c95cic21cb5a6a0cc1fe8@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T21:35:10Z","receivedAt":"2010-01-29T21:35:10Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sverre Rabbelier <srabbelier@gmail.com> writes:\n\n> On Fri, Jan 29, 2010 at 21:48, Junio C Hamano <gitster@pobox.com> wrote:\n>> I think \"not a branch\" is a good suggestion, whether the target of\n>> checkout is \"master^\" or \"origin/topic\".\n>\n> Mhhh, for added clarity, do we want to change it to \"branch name\"? Since ...\n>\n> $ git grep \"branch name\" Documentation/ | wc -l\n> 58\n>\n> ... suggests that we use that in other places as well?\n\nI think the confusion is twofold:\n\n    $ git checkout master^\n    Note: moving to 'master^' which isn't a local branch\n    If you want to create a new branch from this checkout, you may do so\n    ...\n\nThe notice tells us:\n\n - We are moving to 'master^', but it doesn't say what that really means;\n\n - That 'master^' isn't a local branch, but it doesn't say why it matters\n   if it is a local branch (name) or not.\n\nBut what it really should tell new people are:\n\n - The user is no longer on any branch;\n\n - What the implications of not being on any branch are;\n\nYour \"branch _name_\" suggestion deals with another issue that is of lessor\nimportance compared to the above two:\n\n - The _reason_ we are detaching HEAD is because 'master^' did not spell a\n   name of a local branch.\n\n - and perhaps how to be on a branch instead of detaching the head like so.\n\nCompare the current output from \"git checkout $commit\" with output from\n\"git checkout topic\" when you don't have a local branch \"topic\" but have a\nunique remote tracking branch with the same name from a remote, namely\n\"origin\" (that's the UI improvement from Dscho I mentioned in the previous\nmessage):\n\n    $ git checkout topic\n    Branch topic set up to track remote branch topic from origin.\n    Switched to a new branch 'topic'\n\nwhich very clearly explains what is going on.\n\nThe current advisory message tells you what to do to create a new branch,\nbut doesn't explain why you might want to do so (or what is the downside\nof not doing so) in the first place.  That adds to frustration for new\npeople.\n\nSo how about this strawman?\n\n    $ git checkout origin/topic\n    Note: checking out commit 'origin/topic'.\n    You are no longer on any branch. You can look around, make changes and\n    record them in new commits, but any new commit you make from now on will\n    be lost when you check out another branch. If you want to create a new\n    branch from this state to keep them, you may do so (now or later) by\n    using -b with the checkout command again. Example:\n\n      git checkout -b new_branch_name\n\n    HEAD is now at f423ef5... tests: allow user to specify trash direc...\n\nand hide the lines from \"Note: checking out...\" to the blank line before\n\"HEAD is now at\" inside advice.detachedHEAD, so that people who know what\ndetached head is and want to take advantage of it to experiment without\nhaving to worry about cleaning up will have to see only:\n\n    $ git checkout origin/topic\n    HEAD is now at f423ef5... tests: allow user to specify trash direc...\n\n\n\ndiff --git a/advice.c b/advice.c\nindex 936d98b..0be4b5f 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -5,6 +5,7 @@ int advice_status_hints = 1;\n int advice_commit_before_merge = 1;\n int advice_resolve_conflict = 1;\n int advice_implicit_identity = 1;\n+int advice_detached_head = 1;\n \n static struct {\n \tconst char *name;\n@@ -15,6 +16,7 @@ static struct {\n \t{ \"commitbeforemerge\", &advice_commit_before_merge },\n \t{ \"resolveconflict\", &advice_resolve_conflict },\n \t{ \"implicitidentity\", &advice_implicit_identity },\n+\t{ \"detachedhead\", &advice_detached_head },\n };\n \n int git_default_advice_config(const char *var, const char *value)\ndiff --git a/advice.h b/advice.h\nindex 9b7a3ad..3244ebb 100644\n--- a/advice.h\n+++ b/advice.h\n@@ -8,6 +8,7 @@ extern int advice_status_hints;\n extern int advice_commit_before_merge;\n extern int advice_resolve_conflict;\n extern int advice_implicit_identity;\n+extern int advice_detached_head;\n \n int git_default_advice_config(const char *var, const char *value);\n \ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 5277817..0719e54 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -522,8 +522,16 @@ static void update_refs_for_switch(struct checkout_opts *opts,\n \t\tupdate_ref(msg.buf, \"HEAD\", new->commit->object.sha1, NULL,\n \t\t\t   REF_NODEREF, DIE_ON_ERR);\n \t\tif (!opts->quiet) {\n-\t\t\tif (old->path)\n-\t\t\t\tfprintf(stderr, \"Note: moving to '%s' which isn't a local branch\\nIf you want to create a new branch from this checkout, you may do so\\n(now or later) by using -b with the checkout command again. Example:\\n  git checkout -b <new_branch_name>\\n\", new->name);\n+\t\t\tif (old->path && advice_detached_head)\n+\t\t\t\tfprintf(stderr, \n+\"Note: checking out commit '%s'.\\n\"\n+\"You are no longer on any branch. You can look around, make changes and\\n\"\n+\"record them in new commits, but any new commit you make from now on will\\n\"\n+\"be lost when you check out another branch. If you want to create a new\\n\"\n+\"branch from this state to keep them, you may do so (now or later) by\\n\"\n+\"using -b with the checkout command again. Example:\\n\\n\"\n+\"  git checkout -b new_branch_name\\n\\n\",\n+\t\t\t\t\tnew->name);\n \t\t\tdescribe_detached_head(\"HEAD is now at\", new->commit);\n \t\t}\n \t}\n"},{"id":"133010","messageId":"alpine.LFD.2.00.1001291621020.1681@xanadu.home","threadId":"22441","inReplyTo":"1264799342-11093-1-git-send-email-srabbelier@gmail.com","subject":"Re: [PATCH] checkout: warn about 'branch name' rather than 'local branch'","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-29T21:40:39Z","receivedAt":"2010-01-29T21:40:39Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Sverre Rabbelier wrote:\n\n> These days, you can say \"git checkout topic\" to automagically create\n> a local \"topic\" branch that forks from \"origin/topic\" remote tracking\n> branch when you have one, thanks to Dscho's UI improvement ideas. As\n> such it is more appropriate to say that the user is checking out\n> something that is not a branch name, rather than saying it is not a\n> 'local branch'.\n> \n> Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com>\n\nFor the record, I'm providing a NAK.  First I don't agree with the UI \n\"improvement\" if there is no way to check out a remote branch without \ncreating soon-to-be-stall local branches with the same name.\n\nNext, the message can be made yet more clear and give the user more of a \nhint with what is going on.  Something like:\n\n\t\"%s is not a local branch head: creating a detached HEAD\\n\"\n\nplus the remaining clue lines.  This way people will have a much greater \nchance of understanding what state they're in, and a simple Google \nsearch for detached HEAD gives you the Git manual page with the needed \ninfo.\n\n\nNicolas\n"},{"id":"133009","messageId":"ron1-4A6B93.13404629012010@news.gmane.org","threadId":"22441","inReplyTo":"fabb9a1e1001291328s1df443d6jdf0501cda17072de@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-29T21:40:46Z","receivedAt":"2010-01-29T21:40:46Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article \n<fabb9a1e1001291328s1df443d6jdf0501cda17072de@mail.gmail.com>,\n Sverre Rabbelier <srabbelier@gmail.com> wrote:\n\n> Heya,\n> \n> On Fri, Jan 29, 2010 at 22:24, Ron Garret <ron1@flownet.com> wrote:\n> > Yes, I read that.  But what I'm trying to do is not just *look* at the\n> > history, I want to restore my working tree to a previous version.  The\n> > \"Exploring History\" section of the docs doesn't say how to do that.\n> \n> Do you want to restore your working tree only,\n\nYes.\n\n> or also throw away the history?\n\nNo.\n\n> If the former, you could look at 'git revert'\n\nIf that's the right answer then the docs needs serious revision.  The \ndocs for \"git revert\" say that what it does is:\n\n\"Given one existing commit, revert the change the patch introduces, and \nrecord a new commit that records it.\"\n\nwhich does not sound at all like what I'm trying to do.\n\nAll I want to do is copy an old commit to my working tree, nothing else.  \nI don't want to move my head pointer.  I don't want to muck with my \nindex.  I don't want to commit any changes or undo any history.  It's a \nvery simple thing.  It ought to be simple to do, but it doesn't seem to \nbe.\n\nrg\n"},{"id":"133011","messageId":"7vvdekh9kb.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"1264799342-11093-1-git-send-email-srabbelier@gmail.com","subject":"Re: [PATCH] checkout: warn about 'branch name' rather than 'local branch'","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T21:42:44Z","receivedAt":"2010-01-29T21:42:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sverre Rabbelier <srabbelier@gmail.com> writes:\n\n> These days, you can say \"git checkout topic\" to automagically create\n> a local \"topic\" branch that forks from \"origin/topic\" remote tracking\n> branch when you have one, thanks to Dscho's UI improvement ideas. As\n> such it is more appropriate to say that the user is checking out\n> something that is not a branch name, rather than saying it is not a\n> 'local branch'.\n>\n> Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com>\n> ---\n>\n>   Junio, I used part of your reply as the commit message, is that ok?\n>\n>   Only change is s/local branch/branch name/.\n\nI explained why I think that is not solving the real problem.  To a user\nfaced with an unexpected detached HEAD situation, it is not very important\nto explain how we were forced to detach (i.e. because you didn't tell me\nto switch to a branch).\n"},{"id":"133012","messageId":"ron1-A90E72.13434029012010@news.gmane.org","threadId":"22441","inReplyTo":"8c9a061001291325i4b8898b9m46054040c69f8fc6@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-29T21:43:40Z","receivedAt":"2010-01-29T21:43:40Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <8c9a061001291325i4b8898b9m46054040c69f8fc6@mail.gmail.com>,\n Jacob Helwig <jacob.helwig@gmail.com> wrote:\n\n> On Fri, Jan 29, 2010 at 13:16, Ron1 <ron1@flownet.com> wrote:\n> > I know that master^ is a commit and not a branch.  I thought I was\n> > invoking the third variant of git-checkout (as given on the git-checkout\n> > man page) and checking out a commit (which the man page calls a\n> > tree-ish).\n> >\n> > In any case, since my question seems to have sparked some discussion,\n> > I'd like to offer two observations:\n> >\n> > 1.  Saying \"isn't a local branch\" is mightily confusing, because it is\n> > ambiguous whether the problem is that it isn't a branch or if it isn't\n> > local.\n> >\n> > 2.  If I pass something to git checkout (or any other command for that\n> > matter) that it expects to be a branch but isn't a branch it would be\n> > much better if it just gave an error and did nothing rather than give a\n> > (confusing) warning and try to extrapolate the user's intentions.\n> > Whatever a user could possibly mean by 'git checkout master^' it is\n> > almost certainly not what that command actually does at the moment.\n> >\n> \n> I don't think that #2 would be possible.\n\nOf course it's possible.  It git can complain and do something (which is \nwhat it does now) then it can just as easily complain and do nothing.\n\n> My understanding is that\n> branches are basically just there as convenient \"names\" for arbitrary\n> commits.  In other words (in my understanding): There is no place that\n> expects a \"branch\" where a commit (SHA-1) would not work (and be a\n> perfectly valid use).\n\nNo, that's not true.  Branches have names that are recorded separately \nfrom non-branch commits.  It's not a big difference, but it is a \ndifference.\n\nrg\n"},{"id":"133013","messageId":"fabb9a1e1001291345w2723f803sbffb513174445b45@mail.gmail.com","threadId":"22441","inReplyTo":"7vvdekh9kb.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] checkout: warn about 'branch name' rather than 'local branch'","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-01-29T21:45:04Z","receivedAt":"2010-01-29T21:45:04Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Jan 29, 2010 at 22:42, Junio C Hamano <gitster@pobox.com> wrote:\n> I explained why I think that is not solving the real problem.  To a user\n> faced with an unexpected detached HEAD situation, it is not very important\n> to explain how we were forced to detach (i.e. because you didn't tell me\n> to switch to a branch).\n\nI agree your patch is better :).\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"133014","messageId":"7vr5p8h994.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001291614550.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T21:49:27Z","receivedAt":"2010-01-29T21:49:27Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@fluxnic.net> writes:\n\n>> These days, you can say \"git checkout topic\" to automagically create a\n>> local \"topic\" branch that forks from \"origin/topic\" remote tracking branch\n>> when you have one, thanks to Dscho's UI improvement ideas (one less\n>> reason you may end up on a detached HEAD state without wanting to).\n>\n> If this is the case then I'm really disappointed.\n>\n> With all due respects, I don't share Dscho's sentiment about Git's \n> alleged non user-friendliness.  And I always praised Git's ability to \n> use a detached head to check out a remote branch, and never had any \n> problem teaching this concept to people.  So the above is not a UI \n> improvement at all to me.\n\nJust in case you misunderstood...\n\nThis is \"git checkout topic\", not \"git checkout origin/topic\".  The rule\nkicks in when you do not have local branch \"topic\" and there is a unique\n\"refs/remotes/*/topic\".  Existing ways to explicitly ask for detaching are\nunaffected, so \"checkout origin/topic\" or \"checkout origin/topic^0\" do\nwhat you expect.\n\nWe used to just say \"topic is not a rev nor path\" and failed when the user\nsayd \"git checkout topic\".\n\nBecause this cannot be any request other than to check out a local branch\n\"topic\", and because there is no place more sensible than the \"topic\"\ntaken from the \"origin\" (as that is the sole place that has \"topic\"), it\ndwims as a shorthand for \"checkout -b topic origin/topic\" and tells you\nthat it did so.\n"},{"id":"133015","messageId":"ron1-15D04D.13503029012010@news.gmane.org","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001291621020.1681@xanadu.home","subject":"Re: [PATCH] checkout: warn about 'branch name' rather than 'local branch'","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-29T21:50:30Z","receivedAt":"2010-01-29T21:50:30Z","isPatch":true,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <alpine.LFD.2.00.1001291621020.1681@xanadu.home>,\n Nicolas Pitre <nico@fluxnic.net> wrote:\n\n> On Fri, 29 Jan 2010, Sverre Rabbelier wrote:\n> \n> > These days, you can say \"git checkout topic\" to automagically create\n> > a local \"topic\" branch that forks from \"origin/topic\" remote tracking\n> > branch when you have one, thanks to Dscho's UI improvement ideas. As\n> > such it is more appropriate to say that the user is checking out\n> > something that is not a branch name, rather than saying it is not a\n> > 'local branch'.\n> > \n> > Signed-off-by: Sverre Rabbelier <srabbelier@gmail.com>\n> \n> For the record, I'm providing a NAK.  First I don't agree with the UI \n> \"improvement\" if there is no way to check out a remote branch without \n> creating soon-to-be-stall local branches with the same name.\n> \n> Next, the message can be made yet more clear and give the user more of a \n> hint with what is going on.  Something like:\n> \n> \t\"%s is not a local branch head: creating a detached HEAD\\n\"\n> \n> plus the remaining clue lines.  This way people will have a much greater \n> chance of understanding what state they're in, and a simple Google \n> search for detached HEAD gives you the Git manual page with the needed \n> info.\n\nI agree that would be much better.\n\nrg\n"},{"id":"133016","messageId":"alpine.LFD.2.00.1001291641200.1681@xanadu.home","threadId":"22441","inReplyTo":"fabb9a1e1001291332w1d161f8at58aa6fe6908bd77f@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-29T21:51:18Z","receivedAt":"2010-01-29T21:51:18Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Sverre Rabbelier wrote:\n\n> Heya,\n> \n> On Fri, Jan 29, 2010 at 22:29, Nicolas Pitre <nico@fluxnic.net> wrote:\n> > Then who was arguing about making Git more user friendly rather\n> > then less?\n> \n> Using a detached head is a more advanced feature than wanting to\n> checkout a remote branch locally, creating a local tracking branch. As\n> such, 'git checkout origin/topic' now means the same as 'git checkout\n> -t origin/topic', and you can get the old behavior back by doing 'git\n> checkout origin/topic^0'.\n\nWhat purpose does this \"feature\" serve?  Making sure people remain \nstupid and get even more confused when the special dwimery doesn't work \nbecause they don't know the difference between a local branch and a \nremote tracking branch?\n\nAnd now people will be left wondering why after a fetch they don't get \nthe latest stuff when they do \"git checkout topic\" again.  Is this any \nbetter?\n\n> I don't see what the problem is, if you're\n> using a detached head you're an advanced enough git user that you can\n> remember that you can use '^0' to detach your head.\n\nI don't agree with the assertion that a detached HEAD is for advanced \nusers only.\n\n> It's not all that uncommon to do 'git checkout HEAD^0' to detach your \n> head to the current branch, no?\n\nCertainly way more uncommon than 'git checkout origin/foo', and way less \nintuitive.\n\n\nNicolas\n"},{"id":"133017","messageId":"7vmxzwh906.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"fabb9a1e1001291328s1df443d6jdf0501cda17072de@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T21:54:49Z","receivedAt":"2010-01-29T21:54:49Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sverre Rabbelier <srabbelier@gmail.com> writes:\n\n> On Fri, Jan 29, 2010 at 22:24, Ron Garret <ron1@flownet.com> wrote:\n>> Yes, I read that.  But what I'm trying to do is not just *look* at the\n>> history, I want to restore my working tree to a previous version.  The\n>> \"Exploring History\" section of the docs doesn't say how to do that.\n>\n> Do you want to restore your working tree only, or also throw away the\n> history? If the former, you could look at 'git revert',...\n\nI think he wanted to check paths out of a commit and the set of paths\nhappened to be \"everything\".\n\nIOW, \"checkout $commit .\"\n"},{"id":"133018","messageId":"7viqakh8ty.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001291641200.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T21:58:33Z","receivedAt":"2010-01-29T21:58:33Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@fluxnic.net> writes:\n\n> What purpose does this \"feature\" serve?  Making sure people remain \n> stupid and get even more confused when the special dwimery doesn't work \n> because they don't know the difference between a local branch and a \n> remote tracking branch?\n>\n> And now people will be left wondering why after a fetch they don't get \n> the latest stuff when they do \"git checkout topic\" again.  Is this any \n> better?\n\nSverre's explanation does not match reality.\n\nWe used to just say \"topic is not a rev nor path\" and failed when the user\nsaid \"git checkout topic\".  And the magic kicks in when there is only one\n\"remotes/*/topic\".\n\nBecause this cannot be any request other than to check out a local branch\n\"topic\", and because there is no place more sensible than the \"topic\"\ntaken from the \"origin\" (as that is the sole place that has \"topic\"), it\ndwims as a shorthand for \"checkout -b topic origin/topic\" and tells you\nthat it did so.\n\nSo people _has_ to still know that local branches are the only thing they\ncan check out (iow, \"checkout topic\" is not a request to check out a\nremote tracking branch).\n"},{"id":"133019","messageId":"7veil8h8rk.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"ron1-A90E72.13434029012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T21:59:59Z","receivedAt":"2010-01-29T21:59:59Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ron Garret <ron1@flownet.com> writes:\n\n> Of course it's possible.  It git can complain and do something (which is \n> what it does now) then it can just as easily complain and do nothing.\n\nIt is not complaining.  It is telling you that you might have triggered an\nadvanced feature you may not be prepared to use yet.\n\nSo forbidding the advanced feature from everybody won't be a solution.\n"},{"id":"133020","messageId":"fabb9a1e1001291400te0d993dx314720c01c646b8c@mail.gmail.com","threadId":"22441","inReplyTo":"7viqakh8ty.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-01-29T22:00:33Z","receivedAt":"2010-01-29T22:00:33Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Fri, Jan 29, 2010 at 22:58, Junio C Hamano <gitster@pobox.com> wrote:\n> Sverre's explanation does not match reality.\n\nHeh, that's the second time I messed up explaining this new feature,\nmaybe I should stop doing that... eh... my bad.\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"133022","messageId":"ron1-6C7BCB.14122429012010@news.gmane.org","threadId":"22441","inReplyTo":"7vmxzwh906.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-29T22:12:24Z","receivedAt":"2010-01-29T22:12:24Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <7vmxzwh906.fsf@alter.siamese.dyndns.org>,\n Junio C Hamano <gitster@pobox.com> wrote:\n\n> Sverre Rabbelier <srabbelier@gmail.com> writes:\n> \n> > On Fri, Jan 29, 2010 at 22:24, Ron Garret <ron1@flownet.com> wrote:\n> >> Yes, I read that.  But what I'm trying to do is not just *look* at the\n> >> history, I want to restore my working tree to a previous version.  The\n> >> \"Exploring History\" section of the docs doesn't say how to do that.\n> >\n> > Do you want to restore your working tree only, or also throw away the\n> > history? If the former, you could look at 'git revert',...\n> \n> I think he wanted to check paths out of a commit and the set of paths\n> happened to be \"everything\".\n> \n> IOW, \"checkout $commit .\"\n\nYes!!!  That's it exactly!\n\nrg\n"},{"id":"133025","messageId":"ron1-D5CC8E.14184029012010@news.gmane.org","threadId":"22441","inReplyTo":"7veil8h8rk.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-29T22:18:40Z","receivedAt":"2010-01-29T22:18:40Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <7veil8h8rk.fsf@alter.siamese.dyndns.org>,\n Junio C Hamano <gitster@pobox.com> wrote:\n\n> Ron Garret <ron1@flownet.com> writes:\n> \n> > Of course it's possible.  It git can complain and do something (which is \n> > what it does now) then it can just as easily complain and do nothing.\n> \n> It is not complaining.  It is telling you that you might have triggered an\n> advanced feature you may not be prepared to use yet.\n> \n> So forbidding the advanced feature from everybody won't be a solution.\n\ns/complain/warn/\n\nI'm just suggesting that maybe triggering the advanced feature ought not \nto be such an easy thing to do by accident.  It's certainly possible to \nmake that change.  Reasonable people could disagree over whether this is \ndesirable, or whether it would be better to just add this to a FAQ \nsomewhere, or maybe even just leave this as a rite of passage.  \nApparently I'm the first person to ever have this problem or it would \nnot have triggered so much discussion.\n\nrg\n"},{"id":"133028","messageId":"op.u7bfjni44oyyg1@alvarezp-ws","threadId":"22441","inReplyTo":"ron1-1F1799.13340029012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Octavio Alvarez","fromEmail":"alvarezp@alvarezp.ods.org","sentAt":"2010-01-29T22:32:01Z","receivedAt":"2010-01-29T22:32:01Z","isPatch":false,"sender":{"key":"alvarezp@alvarezp.ods.org","avatar":null},"body":"On Fri, 29 Jan 2010 13:34:01 -0800, Ron Garret <ron1@flownet.com> wrote:\n\n> In article <op.u7a909hf4oyyg1@alvarezp-ws>,\n>  \"Octavio Alvarez\" <alvarezp@alvarezp.ods.org> wrote:\n>\n>> On Fri, 29 Jan 2010 12:20:46 -0800, Ron1 <ron1@flownet.com> wrote:\n>>\n>> It means that if you switch to master^ and commit, your commit will\n>> be applied but not tracked (since there is not any branch to advance).\n>>\n>> You would need to do git checkout -b 'new_branch', and then commit.\n>> Now, new_branch will advance with your new commit.\n>\n> OK, I think I understand that.\n>\n> Here's the thing: I can do this:\n>\n> git checkout commit-id filename\n>\n> and restore a particular revision of a particular file to my working\n> tree without affecting my HEAD pointer.  I would expect then that\n>\n> git checkout commit-id\n>\n> with no filename would do the same thing, except restore the entire tree\n> from that commit (including deleting files that didnt' exist then).  And\n> indeed it does that (or at least appears to -- I haven't explored this\n> in depth), except that it DOES move my HEAD pointer to this weird\n> non-branch thing.\n\nI see. You somehow imply that \"git checkout commit-id\" overlaps with\n\"git reset --hard commit-id\".\n\nEven assuming the behavior was not documented in man git-checkout, the\nsecond example looks useless. What is your use case? What would you do\nafter having all the files in the tree switched to another commit,\nwithout actually updating HEAD to the commit, other than git reset --hard\nagain or git revert?\n"},{"id":"133029","messageId":"alpine.LFD.2.00.1001291716070.1681@xanadu.home","threadId":"22441","inReplyTo":"7viqakh8ty.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-29T22:34:28Z","receivedAt":"2010-01-29T22:34:28Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Junio C Hamano wrote:\n\n> We used to just say \"topic is not a rev nor path\" and failed when the user\n> said \"git checkout topic\".  And the magic kicks in when there is only one\n> \"remotes/*/topic\".\n> \n> Because this cannot be any request other than to check out a local branch\n> \"topic\", and because there is no place more sensible than the \"topic\"\n> taken from the \"origin\" (as that is the sole place that has \"topic\"), it\n> dwims as a shorthand for \"checkout -b topic origin/topic\" and tells you\n> that it did so.\n\nOK.  That is probably sensible.\n\nI don't think any improvement on the detached head message should \npresume on this though.\n\nAnd it might be a good idea to say explicitly that what happened is the \ncreation of a detached HEAD, like in:\n\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 5277817..c0a44d7 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -523,7 +523,10 @@ static void update_refs_for_switch(struct checkout_opts *opts,\n \t\t\t   REF_NODEREF, DIE_ON_ERR);\n \t\tif (!opts->quiet) {\n \t\t\tif (old->path)\n-\t\t\t\tfprintf(stderr, \"Note: moving to '%s' which isn't a local branch\\nIf you want to create a new branch from this checkout, you may do so\\n(now or later) by using -b with the checkout command again. Example:\\n  git checkout -b <new_branch_name>\\n\", new->name);\n+\t\t\t\tfprintf(stderr, \"Note: '%s' isn't a local branch head: creating a detached HEAD\\n\"\n+\t\t\t\t\t\t\"If you want to create a new branch from this checkout, you may do so\\n\"\n+\t\t\t\t\t\t\"(now or later) by using -b with the checkout command again. Example:\\n\"\n+\t\t\t\t\t\t\"  git checkout -b <new_branch_name>\\n\", new->name);\n \t\t\tdescribe_detached_head(\"HEAD is now at\", new->commit);\n \t\t}\n \t}\n\n(string split onto multiple lines for easier source reading)\n\nI think this is important to 1) mention the notion of a branch _head_, \nand 2) mention \"detached HEAD\" explicitly for people to be directed to \nappropriate documentation.  So with this change you know exactly what \nhappened and why.\n\n\nNicolas\n"},{"id":"133032","messageId":"7vaavwh6yh.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001291716070.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T22:39:02Z","receivedAt":"2010-01-29T22:39:02Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@fluxnic.net> writes:\n\n> On Fri, 29 Jan 2010, Junio C Hamano wrote:\n>\n>> We used to just say \"topic is not a rev nor path\" and failed when the user\n>> said \"git checkout topic\".  And the magic kicks in when there is only one\n>> \"remotes/*/topic\".\n>> \n>> Because this cannot be any request other than to check out a local branch\n>> \"topic\", and because there is no place more sensible than the \"topic\"\n>> taken from the \"origin\" (as that is the sole place that has \"topic\"), it\n>> dwims as a shorthand for \"checkout -b topic origin/topic\" and tells you\n>> that it did so.\n>\n> OK.  That is probably sensible.\n>\n> I don't think any improvement on the detached head message should \n> presume on this though.\n>\n> And it might be a good idea to say explicitly that what happened is the \n> creation of a detached HEAD, like in:\n\nAny comment on my previous rewording patch ($gmane/138369)?\n\n\"Note: '%s' isn't a local branch head: creating a detached HEAD\\n\"\n\"If you want to create a new branch from this checkout, you may do so\\n\"\n\"(now or later) by using -b with the checkout command again. Example:\\n\"\n\"  git checkout -b <new_branch_name>\\n\", new->name);\n\nA major difference I think is that I avoided a jargon (detached HEAD), and\nchose not to say why the input was interpreted as a request to switch to\nthat state.\n\nOh, of course, I also added advice.detachedHEAD to squelch it ;-)\n"},{"id":"133033","messageId":"8c9a061001291446y1caa5e7cy25d1f19ecf0745e7@mail.gmail.com","threadId":"22441","inReplyTo":"7vaavwh6yh.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Jacob Helwig","fromEmail":"jacob.helwig@gmail.com","sentAt":"2010-01-29T22:46:54Z","receivedAt":"2010-01-29T22:46:54Z","isPatch":false,"sender":{"key":"jacob.helwig@gmail.com","avatar":"https://avatars.githubusercontent.com/u/14557?v=4"},"body":"On Fri, Jan 29, 2010 at 14:39, Junio C Hamano <gitster@pobox.com> wrote:\n> Any comment on my previous rewording patch ($gmane/138369)?\n>\n> \"Note: '%s' isn't a local branch head: creating a detached HEAD\\n\"\n> \"If you want to create a new branch from this checkout, you may do so\\n\"\n> \"(now or later) by using -b with the checkout command again. Example:\\n\"\n> \"  git checkout -b <new_branch_name>\\n\", new->name);\n>\n> A major difference I think is that I avoided a jargon (detached HEAD), and\n> chose not to say why the input was interpreted as a request to switch to\n> that state.\n>\n> Oh, of course, I also added advice.detachedHEAD to squelch it ;-)\n>\n\nFor what it's worth, I'm +1 for this.  Especially the ability to squelch it.\n"},{"id":"133034","messageId":"ron1-0EE62E.14474929012010@news.gmane.org","threadId":"22441","inReplyTo":"op.u7bfjni44oyyg1@alvarezp-ws","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-29T22:47:49Z","receivedAt":"2010-01-29T22:47:49Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <op.u7bfjni44oyyg1@alvarezp-ws>,\n \"Octavio Alvarez\" <alvarezp@alvarezp.ods.org> wrote:\n\n> On Fri, 29 Jan 2010 13:34:01 -0800, Ron Garret <ron1@flownet.com> wrote:\n> \n> > In article <op.u7a909hf4oyyg1@alvarezp-ws>,\n> >  \"Octavio Alvarez\" <alvarezp@alvarezp.ods.org> wrote:\n> >\n> >> On Fri, 29 Jan 2010 12:20:46 -0800, Ron1 <ron1@flownet.com> wrote:\n> >>\n> >> It means that if you switch to master^ and commit, your commit will\n> >> be applied but not tracked (since there is not any branch to advance).\n> >>\n> >> You would need to do git checkout -b 'new_branch', and then commit.\n> >> Now, new_branch will advance with your new commit.\n> >\n> > OK, I think I understand that.\n> >\n> > Here's the thing: I can do this:\n> >\n> > git checkout commit-id filename\n> >\n> > and restore a particular revision of a particular file to my working\n> > tree without affecting my HEAD pointer.  I would expect then that\n> >\n> > git checkout commit-id\n> >\n> > with no filename would do the same thing, except restore the entire tree\n> > from that commit (including deleting files that didnt' exist then).  And\n> > indeed it does that (or at least appears to -- I haven't explored this\n> > in depth), except that it DOES move my HEAD pointer to this weird\n> > non-branch thing.\n> \n> I see. You somehow imply that \"git checkout commit-id\" overlaps with\n> \"git reset --hard commit-id\".\n\nI'm not intentionally implying that.  I don't think git reset --hard \ndoes what I want either (but I could be wrong about that).\n\n> Even assuming the behavior was not documented in man git-checkout, the\n> second example looks useless. What is your use case? What would you do\n> after having all the files in the tree switched to another commit,\n> without actually updating HEAD to the commit, other than git reset --hard\n> again or git revert?\n\nMy actual use case is very complicated, but here's a simplified version:\n\nSuppose I'm using git as a back-end for a wiki.  I want to look at the \nstate of the entire wiki as it was in some point in the past, and I also \nwant to be able to look at the diffs between individual pages as they \nwere then and as they are now.  The most straightforward way I can think \nof to do that is to simply copy an old commit into my working tree \nwithout changing anything else.  Then I can look at the old version by \nsimply looking at the files, and I can get the diffs by simply doing a \ngit diff.\n\nIf I do a git reset --hard then I get the old version, but I lose my \nHEAD pointer so that git diff doesn't give me what I want any more.\n\nBTW, it turns out that git checkout [commit] . doesn't do the right \nthing either.  Apparently, it still updates my index, so git diff still \ndoesn't do the right thing.\n\nrg\n"},{"id":"133036","messageId":"op.u7bg3pby4oyyg1@alvarezp-ws","threadId":"22441","inReplyTo":"ron1-0EE62E.14474929012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Octavio Alvarez","fromEmail":"alvarezp@alvarezp.ods.org","sentAt":"2010-01-29T23:05:39Z","receivedAt":"2010-01-29T23:05:39Z","isPatch":false,"sender":{"key":"alvarezp@alvarezp.ods.org","avatar":null},"body":"On Fri, 29 Jan 2010 14:47:49 -0800, Ron Garret <ron1@flownet.com> wrote:\n>\n> My actual use case is very complicated, but here's a simplified version:\n>\n> Suppose I'm using git as a back-end for a wiki.  I want to look at the\n> state of the entire wiki as it was in some point in the past,\n\nmkdir new_dir; git archive --format=tar tree-ish | tar -C new_dir -x\n\nOf course, this is slower than just checking out the files that differ,\nI agree.\n\n> and I also\n> want to be able to look at the diffs between individual pages as they\n> were then and as they are now.\n\ngit diff commit-ish1 commit-ish2 file1 file2 ...\n\nOr you could just clone it and compare whatever you want there and just\nerase when done. This would allow you to do \"git pull\" from the origin.\n\n> If I do a git reset --hard then I get the old version, but I lose my\n> HEAD pointer so that git diff doesn't give me what I want any more.\n\nYou could tag the current version before resetting and then issue\ngit reset --hard the_tag, but I guess you would run into race conditions:\nsomeone updates the wiki while the HEAD is in another commit.\n\nHope it helps. :-)\n"},{"id":"133037","messageId":"7vk4v0fqts.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"ron1-0EE62E.14474929012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-29T23:12:47Z","receivedAt":"2010-01-29T23:12:47Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ron Garret <ron1@flownet.com> writes:\n\n> My actual use case is very complicated, but here's a simplified version:\n>\n> Suppose I'm using git as a back-end for a wiki.  I want to look at the \n> state of the entire wiki as it was in some point in the past, and I also \n> want to be able to look at the diffs between individual pages as they \n> were then and as they are now.\n\nDon't think you are so special ;-) \"git checkout $that_old_commit\" was\ninvented _exactly_ for that use case.  You can look around from that\nstate, and when you are done sightseeing, you can come back by doing a\n\"git checkout master\" (or whichever branch you want to be on).\n\nYou don't necessarily have to check out an old state if the only thing\nyou are interested in is to review how the contents changed over time.\nUse \"git log -p\" (from the current tip) for that.\n\nIf you chose to have an old checkout and then traverse the changes over\ntime leading to the current tip, you would say \"git log -p ..master\"\ninstead.\n"},{"id":"133038","messageId":"4B636C3B.8040308@gmail.com","threadId":"22441","inReplyTo":"fabb9a1e1001291332w1d161f8at58aa6fe6908bd77f@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"A Large Angry SCM","fromEmail":"gitzilla@gmail.com","sentAt":"2010-01-29T23:16:11Z","receivedAt":"2010-01-29T23:16:11Z","isPatch":false,"sender":{"key":"gitzilla@gmail.com","avatar":"https://gravatar.com/avatar/354625c442439908ff3dd99757dee330e29e9df7847472384faf7a00add247fb?d=mp&s=160"},"body":"Sverre Rabbelier wrote:\n> Heya,\n> \n> On Fri, Jan 29, 2010 at 22:29, Nicolas Pitre <nico@fluxnic.net> wrote:\n>> Then who was arguing about making Git more user friendly rather\n>> then less?\n> \n> Using a detached head is a more advanced feature than wanting to\n> checkout a remote branch locally, creating a local tracking branch. As\n> such, 'git checkout origin/topic' now means the same as 'git checkout\n> -t origin/topic', and you can get the old behavior back by doing 'git\n> checkout origin/topic^0'. I don't see what the problem is, if you're\n> using a detached head you're an advanced enough git user that you can\n> remember that you can use '^0' to detach your head. It's not all that\n> uncommon to do 'git checkout HEAD^0' to detach your head to the\n> current branch, no?\n> \n\n[I'm still catching up on this thread]\n\nWhat we call 'Detached head' is _the_ normal way ti use git for quite a \nnumber of users. And given the current UI, it's not really advanced.\n"},{"id":"133040","messageId":"bd7fb2a884e55e176eea3002fd0c68dd@212.159.54.234","threadId":"22441","inReplyTo":"ron1-0EE62E.14474929012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Julian Phillips","fromEmail":"julian@quantumfyre.co.uk","sentAt":"2010-01-29T23:28:48Z","receivedAt":"2010-01-29T23:28:48Z","isPatch":false,"sender":{"key":"julian@quantumfyre.co.uk","avatar":"https://avatars.githubusercontent.com/u/948888?v=4"},"body":"On Fri, 29 Jan 2010 14:47:49 -0800, Ron Garret <ron1@flownet.com> wrote:\n> My actual use case is very complicated, but here's a simplified version:\n> \n> Suppose I'm using git as a back-end for a wiki.  I want to look at the \n> state of the entire wiki as it was in some point in the past, and I also\n\n> want to be able to look at the diffs between individual pages as they \n> were then and as they are now.  The most straightforward way I can think\n\n> of to do that is to simply copy an old commit into my working tree \n> without changing anything else.  Then I can look at the old version by \n> simply looking at the files, and I can get the diffs by simply doing a \n> git diff.\n> \n> If I do a git reset --hard then I get the old version, but I lose my \n> HEAD pointer so that git diff doesn't give me what I want any more.\n> \n> BTW, it turns out that git checkout [commit] . doesn't do the right \n> thing either.  Apparently, it still updates my index, so git diff still \n> doesn't do the right thing.\n\nIf I understand what you want correctly, then:\n\ngit diff --cached -R [path]\n\nshould be the appropriate command after the \"git checkout <commit> .\".\n\n-- \nJulian\n"},{"id":"133039","messageId":"ron1-D69CAB.15304829012010@news.gmane.org","threadId":"22441","inReplyTo":"7vk4v0fqts.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-29T23:30:48Z","receivedAt":"2010-01-29T23:30:48Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <7vk4v0fqts.fsf@alter.siamese.dyndns.org>,\n Junio C Hamano <gitster@pobox.com> wrote:\n\n> Ron Garret <ron1@flownet.com> writes:\n> \n> > My actual use case is very complicated, but here's a simplified version:\n> >\n> > Suppose I'm using git as a back-end for a wiki.  I want to look at the \n> > state of the entire wiki as it was in some point in the past, and I also \n> > want to be able to look at the diffs between individual pages as they \n> > were then and as they are now.\n> \n> Don't think you are so special ;-)\n\nNever.  :-)\n\n> \"git checkout $that_old_commit\" was\n> invented _exactly_ for that use case.  You can look around from that\n> state, and when you are done sightseeing, you can come back by doing a\n> \"git checkout master\" (or whichever branch you want to be on).\n\nYes, that's what I would have expected.  Except that it not only updates \nmy working tree, it updates my head also, so git diff doesn't give me \nthe diffs that I want.  (This makes sense for the usual use case.)\n\n> You don't necessarily have to check out an old state if the only thing\n> you are interested in is to review how the contents changed over time.\n> Use \"git log -p\" (from the current tip) for that.\n> \n> If you chose to have an old checkout and then traverse the changes over\n> time leading to the current tip, you would say \"git log -p ..master\"\n> instead.\n\nThere's also this:\n\n\ngit rev-list HEAD -- [filename]\n\ngit ls-tree [some-hash-from-the-list-above]\n\nThen for each line in the result:\n\ngit cat-file blob [hash] > [filename]\n\n\nwhich seems like a horrible hack, but actually does what I want.\n\nrg\n"},{"id":"133041","messageId":"alpine.LFD.2.00.1001291833580.1681@xanadu.home","threadId":"22441","inReplyTo":"7vaavwh6yh.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-29T23:43:41Z","receivedAt":"2010-01-29T23:43:41Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Junio C Hamano wrote:\n\n> Any comment on my previous rewording patch ($gmane/138369)?\n\nA bit too verbose (even if it can be configured out) and frightening I'd \nsay.\n\n> \"Note: '%s' isn't a local branch head: creating a detached HEAD\\n\"\n> \"If you want to create a new branch from this checkout, you may do so\\n\"\n> \"(now or later) by using -b with the checkout command again. Example:\\n\"\n> \"  git checkout -b <new_branch_name>\\n\", new->name);\n> \n> A major difference I think is that I avoided a jargon (detached HEAD), and\n> chose not to say why the input was interpreted as a request to switch to\n> that state.\n\nTo the contrary, I think it is about time we use proper Git jargon.  \nOtherwise how can we expect people to relate to the documentation where \nthat jargon is indeed used?  Even on this very mailing list we refer to \nthat state as a \"detached HEAD\".  And Google gives precisely the right \ninfo with \"detached HEAD\" while any other verbiage might not.\n\nAnd just saying that \"you're not on any branch anymore\" is still leaving \nthe user wondering why.  At least with the \"isn't a local branch head\" \nthe user has 2 clues: it has to be a _local_ branch and a branch _head_ \nnot to create a detached HEAD.  So I still prefer the above rewording.\n\n> Oh, of course, I also added advice.detachedHEAD to squelch it ;-)\n\nThat is indeed an excellent idea.\n\n\nNicolas\n"},{"id":"133043","messageId":"7vy6jgcutb.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001291833580.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T00:14:56Z","receivedAt":"2010-01-30T00:14:56Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@fluxnic.net> writes:\n\n> To the contrary, I think it is about time we use proper Git jargon.  \n> Otherwise how can we expect people to relate to the documentation where \n> that jargon is indeed used?  Even on this very mailing list we refer to \n> that state as a \"detached HEAD\".  And Google gives precisely the right \n> info with \"detached HEAD\" while any other verbiage might not.\n>\n> And just saying that \"you're not on any branch anymore\" is still leaving \n> the user wondering why.  At least with the \"isn't a local branch head\" \n> the user has 2 clues: it has to be a _local_ branch and a branch _head_ \n> not to create a detached HEAD.  So I still prefer the above rewording.\n\nI can buy that argument, except for three minor points:\n\n - I think we also should give information necessary to judge if the user\n   wants to stay in the detached HEAD state.  IOW, \"Why am I getting an\n   insn to create a new branch?  What is wrong with this detached HEAD\n   state?  Why would I want a local branch?\" are still not explained with\n   the updated message.\n\n - Do we \"create\" a detached HEAD, or are we just \"detaching HEAD\"?\n\n - Running \"checkout -b\" now will create a new branch from that checkout,\n   but doing so _later_ won't necessarily do so from that _checkout_.\n\nSo how about doing this (changes to advice.[ch] are omitted)?\n\ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 5277817..41fc00a 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -522,8 +522,16 @@ static void update_refs_for_switch(struct checkout_opts *opts,\n \t\tupdate_ref(msg.buf, \"HEAD\", new->commit->object.sha1, NULL,\n \t\t\t   REF_NODEREF, DIE_ON_ERR);\n \t\tif (!opts->quiet) {\n-\t\t\tif (old->path)\n-\t\t\t\tfprintf(stderr, \"Note: moving to '%s' which isn't a local branch\\nIf you want to create a new branch from this checkout, you may do so\\n(now or later) by using -b with the checkout command again. Example:\\n  git checkout -b <new_branch_name>\\n\", new->name);\n+\t\t\tif (old->path && advice_detached_head)\n+\t\t\t\tfprintf(stderr,\n+\"Note: '%s' isn't a local branch head.\\n\\n\"\n+\"HEAD is detached at that commit. You can look around, even make changes\\n\"\n+\"and record them in new commits, but any new commit you make from now on\\n\"\n+\"will be lost when you check out another branch.\\n\"\n+\"If you want to create a new branch from this state, you may do so\\n\"\n+\"(now or later) by using -b with the checkout command again. Example:\\n\"\n+\"  git checkout -b <new_branch_name>\\n\\n\",\n+\t\t\t\t\tnew->name);\n \t\t\tdescribe_detached_head(\"HEAD is now at\", new->commit);\n \t\t}\n \t}\n"},{"id":"133044","messageId":"ron1-A99355.16145629012010@news.gmane.org","threadId":"22441","inReplyTo":"bd7fb2a884e55e176eea3002fd0c68dd@212.159.54.234","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-30T00:14:56Z","receivedAt":"2010-01-30T00:14:56Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <bd7fb2a884e55e176eea3002fd0c68dd@212.159.54.234>,\n Julian Phillips <julian@quantumfyre.co.uk> wrote:\n\n> On Fri, 29 Jan 2010 14:47:49 -0800, Ron Garret <ron1@flownet.com> wrote:\n> > My actual use case is very complicated, but here's a simplified version:\n> > \n> > Suppose I'm using git as a back-end for a wiki.  I want to look at the \n> > state of the entire wiki as it was in some point in the past, and I also\n> \n> > want to be able to look at the diffs between individual pages as they \n> > were then and as they are now.  The most straightforward way I can think\n> \n> > of to do that is to simply copy an old commit into my working tree \n> > without changing anything else.  Then I can look at the old version by \n> > simply looking at the files, and I can get the diffs by simply doing a \n> > git diff.\n> > \n> > If I do a git reset --hard then I get the old version, but I lose my \n> > HEAD pointer so that git diff doesn't give me what I want any more.\n> > \n> > BTW, it turns out that git checkout [commit] . doesn't do the right \n> > thing either.  Apparently, it still updates my index, so git diff still \n> > doesn't do the right thing.\n> \n> If I understand what you want correctly, then:\n> \n> git diff --cached -R [path]\n> \n> should be the appropriate command after the \"git checkout <commit> .\".\n\nYep, that works.  Alternatively, is there a way to clear the index?  \nSeems like that would be better.\n\nrg\n"},{"id":"133045","messageId":"fabb9a1e1001291618m71f61209v4f26fb66c6ad99ae@mail.gmail.com","threadId":"22441","inReplyTo":"7vy6jgcutb.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-01-30T00:18:33Z","receivedAt":"2010-01-30T00:18:33Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Sat, Jan 30, 2010 at 01:14, Junio C Hamano <gitster@pobox.com> wrote:\n> +\"If you want to create a new branch from this state, you may do so\\n\"\n> +\"(now or later) by using -b with the checkout command again.\n\nI think the \"this state\" needs to be changed, it currently suggests\nwhat you mention earlier in you reply, that it's about the current\nstate, even if you make commits on top of that. Maybe something in the\nspirit of \"If you want to create a new branch from ?? where you are at\nthe moment you follow these instructions ??\".\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"133046","messageId":"ron1-4F99DE.16184529012010@news.gmane.org","threadId":"22441","inReplyTo":"ron1-A99355.16145629012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-30T00:18:45Z","receivedAt":"2010-01-30T00:18:45Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <ron1-A99355.16145629012010@news.gmane.org>,\n Ron Garret <ron1@flownet.com> wrote:\n\n> In article <bd7fb2a884e55e176eea3002fd0c68dd@212.159.54.234>,\n>  Julian Phillips <julian@quantumfyre.co.uk> wrote:\n> \n> > On Fri, 29 Jan 2010 14:47:49 -0800, Ron Garret <ron1@flownet.com> wrote:\n> > > My actual use case is very complicated, but here's a simplified version:\n> > > \n> > > Suppose I'm using git as a back-end for a wiki.  I want to look at the \n> > > state of the entire wiki as it was in some point in the past, and I also\n> > \n> > > want to be able to look at the diffs between individual pages as they \n> > > were then and as they are now.  The most straightforward way I can think\n> > \n> > > of to do that is to simply copy an old commit into my working tree \n> > > without changing anything else.  Then I can look at the old version by \n> > > simply looking at the files, and I can get the diffs by simply doing a \n> > > git diff.\n> > > \n> > > If I do a git reset --hard then I get the old version, but I lose my \n> > > HEAD pointer so that git diff doesn't give me what I want any more.\n> > > \n> > > BTW, it turns out that git checkout [commit] . doesn't do the right \n> > > thing either.  Apparently, it still updates my index, so git diff still \n> > > doesn't do the right thing.\n> > \n> > If I understand what you want correctly, then:\n> > \n> > git diff --cached -R [path]\n> > \n> > should be the appropriate command after the \"git checkout <commit> .\".\n> \n> Yep, that works.  Alternatively, is there a way to clear the index?  \n> Seems like that would be better.\n\nWell, whaddyaknow: git reset without any arguments has a use after all \n:-)\n\nrg\n"},{"id":"133047","messageId":"7viqakcu56.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"fabb9a1e1001291618m71f61209v4f26fb66c6ad99ae@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T00:29:25Z","receivedAt":"2010-01-30T00:29:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Sverre Rabbelier <srabbelier@gmail.com> writes:\n\n> I think the \"this state\" needs to be changed, it currently suggests\n> what you mention earlier in you reply, that it's about the current\n> state, even if you make commits on top of that. Maybe something in the\n> spirit of \"If you want to create a new branch from ?? where you are at\n> the moment you follow these instructions ??\".\n\nTrue.  And I am a moron.\n\nThe \"state\" was not about the work-tree state, but about the\n\"detached HEAD\" state, which I didn't make it clear.\n\nI also didn't address \"scariness\" point from Nico.  And scariness can be\nremoved by describing things in a positive way.\n\nHow about this?\n\n-- >8 -- not a patch -- >8 --\nNote: 'master^0' isn't a local branch head;\n\nYou are in 'detached HEAD' state. You can look around, make experimental\nchanges and commit them, and you can discard any commits you make in this\nstate without impacting any branches by checking out another branch.\n\nIf you want to create a new branch to retain commits you create, you may\ndo so (now or later) by using -b with the checkout command again. Example:\n\n  git checkout -b <new_branch_name>\n\nHEAD is now at a9d7c95... Merge branch 'maint'\n-- 8< -- not a patch -- 8< --\n\nAgain, everything except for the last line would disappear by setting the\nadvice.detachedHEAD configuration to false.\n"},{"id":"133048","messageId":"b4087cc51001291633l68760880i340d12e865641077@mail.gmail.com","threadId":"22441","inReplyTo":"ron1-6C7BCB.14122429012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2010-01-30T00:33:56Z","receivedAt":"2010-01-30T00:33:56Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"On Fri, Jan 29, 2010 at 4:12 PM, Ron Garret <ron1@flownet.com> wrote:\n> In article <7vmxzwh906.fsf@alter.siamese.dyndns.org>,\n>  Junio C Hamano <gitster@pobox.com> wrote:\n>\n>> Sverre Rabbelier <srabbelier@gmail.com> writes:\n>>\n>> > On Fri, Jan 29, 2010 at 22:24, Ron Garret <ron1@flownet.com> wrote:\n>> >> Yes, I read that.  But what I'm trying to do is not just *look* at the\n>> >> history, I want to restore my working tree to a previous version.  The\n>> >> \"Exploring History\" section of the docs doesn't say how to do that.\n>> >\n>> > Do you want to restore your working tree only, or also throw away the\n>> > history? If the former, you could look at 'git revert',...\n>>\n>> I think he wanted to check paths out of a commit and the set of paths\n>> happened to be \"everything\".\n>>\n>> IOW, \"checkout $commit .\"\n>\n> Yes!!!  That's it exactly!\n\nHowever, that updates the index and doesn't delete files that didn't\nexist in $commit, and you said earlier that you don't want to update\nthe index (though perhaps you didn't really know what you wanted\nthere).\n\nMy idea:\n\nIsn't the difference between 'checkout' and 'reset' almost essentially\na matter of whether the branch reference (HEAD), index, and tree are\nmodified? Couldn't these commands be merged into one command or make\nuse of one command?\n\nRather than relying on flags like --hard, --soft, and --mixed, why not\n*also* provide flags for specifying at a finer granularity what is\ndesired for the index, working tree, and HEAD.\n\nThen:\n    git checkout $commit\ndoes a lot of its work through something like:\n    git update --index --tree --detach $commit\n\nAlso:\n    git checkout $commit $f\ntranslates:\n    git update --index --tree --keep-tracked-files $commit $f\n\nAlso:\n    git reset [--mixed] $commit\ntranslates:\n    git update --index --head $commit\n\nAlso:\n    git reset --soft $commit\ntranslates:\n    git update --head $commit\n\nAlso:\n    git reset --hard $commit\ntranslates:\n    git update --index --tree --head $commit\n\nAnd so on.\n\nIn fact, with --no-* flags, you could modify 'reset' and 'checkout'\ncommands from their defaults. So, to update all of the paths\n(including deleting tracked files not in $commit), but keep the index\nuntouched, we have:\n\n    git checkout --no-update-index --no-update-keep-files $commit .\n\nOf course, you might as well just use the hypothetical 'update'\ncommand directly:\n\n    git update --tree $commit .\n\nSincerely,\nMichael Witten\n"},{"id":"133049","messageId":"fabb9a1e1001291635n34eaf17eh5d0cf5a535e3d9c4@mail.gmail.com","threadId":"22441","inReplyTo":"7viqakcu56.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-01-30T00:35:06Z","receivedAt":"2010-01-30T00:35:06Z","isPatch":false,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Sat, Jan 30, 2010 at 01:29, Junio C Hamano <gitster@pobox.com> wrote:\n> True.  And I am a moron.\n\nNot at all, you worded it very nicely I think.\n\n> How about this?\n\nDefinitely a major improvement, nice.\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"133050","messageId":"b4087cc51001291638y5620eb3epd86efe577ab7adb1@mail.gmail.com","threadId":"22441","inReplyTo":"7viqakcu56.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2010-01-30T00:38:32Z","receivedAt":"2010-01-30T00:38:32Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"On Fri, Jan 29, 2010 at 6:29 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> The \"state\" was not about the work-tree state, but about the\n> \"detached HEAD\" state, which I didn't make it clear.\n\nMaybe we should just introduce people to a more explicit command like\nthe hypothetical 'update' command I sketch here:\n\n    http://marc.info/?l=git&m=126481166426896&w=2\n"},{"id":"133051","messageId":"alpine.LFD.2.00.1001291935080.1681@xanadu.home","threadId":"22441","inReplyTo":"7viqakcu56.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-30T00:39:41Z","receivedAt":"2010-01-30T00:39:41Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Junio C Hamano wrote:\n\n> How about this?\n> \n> -- >8 -- not a patch -- >8 --\n> Note: 'master^0' isn't a local branch head;\n> \n> You are in 'detached HEAD' state. You can look around, make experimental\n> changes and commit them, and you can discard any commits you make in this\n> state without impacting any branches by checking out another branch.\n\ns/checking out another branch/performing another checkout/\n\n> If you want to create a new branch to retain commits you create, you may\n> do so (now or later) by using -b with the checkout command again. Example:\n> \n>   git checkout -b <new_branch_name>\n> \n> HEAD is now at a9d7c95... Merge branch 'maint'\n> -- 8< -- not a patch -- 8< --\n> \n> Again, everything except for the last line would disappear by setting the\n> advice.detachedHEAD configuration to false.\n\nLooks fine to me.\n\n\nNicolas\n"},{"id":"133053","messageId":"ca433831001291701m50b8c2b7p16bcc6fd4f3f3d55@mail.gmail.com","threadId":"22441","inReplyTo":"7viqakcu56.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Mark Lodato","fromEmail":"lodatom@gmail.com","sentAt":"2010-01-30T01:01:40Z","receivedAt":"2010-01-30T01:01:40Z","isPatch":false,"sender":{"key":"lodatom@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58860?v=4"},"body":"On Fri, Jan 29, 2010 at 7:29 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> How about this?\n>\n> -- >8 -- not a patch -- >8 --\n> Note: 'master^0' isn't a local branch head;\n>\n> You are in 'detached HEAD' state. You can look around, make experimental\n> changes and commit them, and you can discard any commits you make in this\n> state without impacting any branches by checking out another branch.\n>\n> If you want to create a new branch to retain commits you create, you may\n> do so (now or later) by using -b with the checkout command again. Example:\n>\n>  git checkout -b <new_branch_name>\n>\n> HEAD is now at a9d7c95... Merge branch 'maint'\n> -- 8< -- not a patch -- 8< --\n\nFirst off, I would like to voice support for such a warning.  This is\nso much more clear than the current message.\n\nStill, I find it slightly confusing and unfriendly.  How about the following?\n\n-- >8 -- not a patch -- >8 --\nChecking out commit 'master^0'.\n\nSince this is not a local branch head, any commits you make will be lost\nwhen you check out another branch or commit.  (In git terminology, HEAD\nis detached.)  If you just wish to look at files without committing,\nthis is fine.  If you wish to make commits and retain them, you may\ncreate a new branch by running:\n\n  git checkout -b <new_branch_name>\n\nHEAD is now at a9d7c95... Merge branch 'maint'\n - 8< -- not a patch -- 8< --\n\nI think the above wording is fine for both commits (e.g. master^0) and\nremote branches (e.g. origin/pu).  With other wording, we may wish to\nhave two slightly different messages depending on what the user typed.\n\nAlso, I am not a big fan of \"local branch head\".  How about \"not the\nname of a local branch\"?  I'm not sure...\n"},{"id":"133058","messageId":"alpine.LFD.2.00.1001292013150.1681@xanadu.home","threadId":"22441","inReplyTo":"ca433831001291701m50b8c2b7p16bcc6fd4f3f3d55@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-30T01:22:33Z","receivedAt":"2010-01-30T01:22:33Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Mark Lodato wrote:\n\n> Still, I find it slightly confusing and unfriendly.  How about the following?\n\nIt is slightly inaccurate.\n\n> Checking out commit 'master^0'.\n> \n> Since this is not a local branch head, any commits you make will be lost\n> when you check out another branch or commit.  (In git terminology, HEAD\n> is detached.)  If you just wish to look at files without committing,\n> this is fine.  If you wish to make commits and retain them, you may\n> create a new branch by running:\n> \n>   git checkout -b <new_branch_name>\n\nThis gives the impression that any commit you make on a detached HEAD \nare going to be lost, unless you create a new branch first.\n\nAnd again, it is a good thing to have \"detached HEAD\" in there so to \nrelate to existing documentation easily.\n\n> I think the above wording is fine for both commits (e.g. master^0) and\n> remote branches (e.g. origin/pu).  With other wording, we may wish to\n> have two slightly different messages depending on what the user typed.\n\nYou could have tags too.  So instead of trying to be too smart, it is \nbest to simply display the provided name without qualifier.\n\n> Also, I am not a big fan of \"local branch head\".  How about \"not the\n> name of a local branch\"?  I'm not sure...\n\nThe confusion that started this thread was about \"master^\" which might \nbe interpreted as the name of a local branch except for the fact that we \nwant one commit back.  So using \"local commit head\" is more precise.\n\n\nNicolas\n"},{"id":"133063","messageId":"alpine.DEB.1.00.1001300312450.3749@intel-tinevez-2-302","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001291614550.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2010-01-30T02:13:55Z","receivedAt":"2010-01-30T02:13:55Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 29 Jan 2010, Nicolas Pitre wrote:\n\n> With all due respects, I don't share Dscho's sentiment about Git's \n> alleged non user-friendliness.\n\nOf course you don't.  You are a Git oldtimer.  Probably you do not even \nhave much exposure to complete programming newbies.\n\nWell, guess what.  I have.  And guess what even more: they are the \nmajority, not you and me.\n\nCiao,\nDscho\n"},{"id":"133067","messageId":"ron1-F006CF.18381129012010@news.gmane.org","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001292013150.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-30T02:38:11Z","receivedAt":"2010-01-30T02:38:11Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <alpine.LFD.2.00.1001292013150.1681@xanadu.home>,\n Nicolas Pitre <nico@fluxnic.net> wrote:\n\n> On Fri, 29 Jan 2010, Mark Lodato wrote:\n> \n> > Still, I find it slightly confusing and unfriendly.  How about the \n> > following?\n> \n> It is slightly inaccurate.\n> \n> > Checking out commit 'master^0'.\n> > \n> > Since this is not a local branch head, any commits you make will be lost\n> > when you check out another branch or commit.  (In git terminology, HEAD\n> > is detached.)  If you just wish to look at files without committing,\n> > this is fine.  If you wish to make commits and retain them, you may\n> > create a new branch by running:\n> > \n> >   git checkout -b <new_branch_name>\n> \n> This gives the impression that any commit you make on a detached HEAD \n> are going to be lost, unless you create a new branch first.\n> \n> And again, it is a good thing to have \"detached HEAD\" in there so to \n> relate to existing documentation easily.\n> \n> > I think the above wording is fine for both commits (e.g. master^0) and\n> > remote branches (e.g. origin/pu).  With other wording, we may wish to\n> > have two slightly different messages depending on what the user typed.\n> \n> You could have tags too.  So instead of trying to be too smart, it is \n> best to simply display the provided name without qualifier.\n> \n> > Also, I am not a big fan of \"local branch head\".  How about \"not the\n> > name of a local branch\"?  I'm not sure...\n> \n> The confusion that started this thread was about \"master^\" which might \n> be interpreted as the name of a local branch except for the fact that we \n> want one commit back.  So using \"local commit head\" is more precise.\n\nSince it is my confusion that started this thread (and I suppose is in \npart responsible for continuing it) I should be clear that master^ was \njust an example.  My first attempt to roll back to an earlier version \nwas actually \"git checkout HEAD^\".  That produced the same result, since \nHEAD was pointing to master at the time.  But one of the things I \nrealized was that HEAD was a variable, and so I chose to frame my \nexample in terms of master instead of HEAD in order to eliminate \nambiguity.\n\nFWIW, here are some observations based on my current understanding:\n\n1.  The term \"detached HEAD\" is inherently misleading.  A detached HEAD \nisn't detached from anything, it's just pointing to the middle of a \nbranch, which is to say, to a commit that happens to already have \ndescendants.  For that matter, the name HEAD is itself misleading, since \nHEAD need not be the head of a branch (though normally it is).  A better \nname for HEAD would have been CURRENT or ACTIVE.  I recognize it's \nprobably too late to change it now.\n\n2.  There are a lot of things in the documentation that turn out, now \nthat I understand what is going on, to be subtly misleading.  For \nexample, \"A single git repository can track development on multiple \nbranches. It does this by keeping a list of heads which reference the \nlatest commit on each branch.\"  That last part is only true if the heads \nare not \"detached\".\n\nI do not yet understand enough about git to know if this is a reasonable \nsuggestion, but one possibility is to separate the notion of a head from \nthe notion of a pointer to a commit.  A head would be a pointer to a \ncommit that can only point to a commit with no descendants, whereas a \npointer could point anywhere.  What is now called HEAD would be a \npointer, not a head under this ontology.\n\nAnother example: \"The HEAD then refers to the SHA-1 of the commit \ninstead of to a branch, and git branch shows that you are no longer on a \nbranch:\"  But you *are* on a branch, you just aren't at the head of the \nbranch.  In fact, by the definition of branch the whole concept of \"not \nbeing on a branch\" is non-sensical.  (Isn't that part of the whole point \nof git?  That everything is a branch?)\n\n3.  These observations suggest ways in which the situation could be \nimproved.\n\nFirst, I think Michael Witten is on the right track with his proposal \nfor a redesign of git-checkout and the new git-update command (though I \nhave not yet had time to think deeply about the details).  There are \nonly a small number of things that are actually going on under the hood, \nand the closer the map between the command set and those primitive \noperations can be made the better.\n\nSecond, the real problem underlying the original warning that started \nall this is that if you do a commit from a \"detached head\" then you have \neffectively created a branch whether you meant to or not.  This suggests \na very straightforward warning:\n\n\"WARNING: Your HEAD is now pointing to a commit that has descendants.\nIf you do a commit from here, you will be creating a branch.  If this\nis not what you intend, read the documentation and achieve clarity before\nproceeding.  If you just want to bail out of this situation without\ndoing your homework, do a 'git checkout master' or something like that.\"\n\nOr something like that :-)\n\nrg\n"},{"id":"133066","messageId":"ca433831001291840o751fa02eve1ae301537674325@mail.gmail.com","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001292013150.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Mark Lodato","fromEmail":"lodatom@gmail.com","sentAt":"2010-01-30T02:40:03Z","receivedAt":"2010-01-30T02:40:03Z","isPatch":false,"sender":{"key":"lodatom@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58860?v=4"},"body":"On Fri, Jan 29, 2010 at 8:22 PM, Nicolas Pitre <nico@fluxnic.net> wrote:\n> On Fri, 29 Jan 2010, Mark Lodato wrote:\n>\n>> Still, I find it slightly confusing and unfriendly.  How about the following?\n>\n> It is slightly inaccurate.\n\nIs the following the only inaccuracy?  Do you have any other feedback?\n\n>> Checking out commit 'master^0'.\n>>\n>> Since this is not a local branch head, any commits you make will be lost\n>> when you check out another branch or commit.  (In git terminology, HEAD\n>> is detached.)  If you just wish to look at files without committing,\n>> this is fine.  If you wish to make commits and retain them, you may\n>> create a new branch by running:\n>>\n>>   git checkout -b <new_branch_name>\n>\n> This gives the impression that any commit you make on a detached HEAD\n> are going to be lost, unless you create a new branch first.\n\nWhat about \"...you may want to create...\"?  This does not imply that\ncreating a new branch now is the *only* way, just the most likely.  If\na user knows another way, that user probably does not need this\nwarning in the first place.\n"},{"id":"133069","messageId":"7vbpgc8fhb.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"ron1-F006CF.18381129012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T02:59:44Z","receivedAt":"2010-01-30T02:59:44Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ron Garret <ron1@flownet.com> writes:\n\n> 1.  The term \"detached HEAD\" is inherently misleading.  A detached HEAD \n> isn't detached from anything, it's just pointing to the middle of a \n> branch, which is to say, to a commit that happens to already have \n> descendants.  For that matter, the name HEAD is itself misleading, since \n> HEAD need not be the head of a branch (though normally it is).  A better \n> name for HEAD would have been CURRENT or ACTIVE.  I recognize it's \n> probably too late to change it now.\n\nThis description, especially the phrase \"middle of a branch\" shows that\nyou don't understand git yet.  A git branch is _not_ a line (nor multiple\nlines) of development.  It is merely a _point_ in the history.\n\n\"A commit that is in the middle of an ancestry chain with existing\ndescendants\" can be at the tip of a branch and does not have anything to\ndo with detached HEAD state.\n\nWhen HEAD points at a branch, making a commit advances _that_ branch.  And\nwe say you are \"on that branch\".  When HEAD is detached, because it is not\nattached to anything, it advances no branch.  \"detached HEAD\" is detached\nin the very real sense.  It is not attached to _any_ branch.\n\n> 2.  There are a lot of things in the documentation that turn out, now \n> that I understand what is going on, to be subtly misleading.  For \n> example, \"A single git repository can track development on multiple \n> branches. It does this by keeping a list of heads which reference the \n> latest commit on each branch.\"  That last part is only true if the heads \n> are not \"detached\".\n\nThis is from old terminology.  We used to use \"head\" (lowercase) and\n\"branches\" pretty much interchangeably and the quoted description is from\nthe era _before_ detached HEAD was invented, as a way to quickly get a\ntemporary state where you can browse around freely and without having to\nworry about having to clean up afterwards even if you made commits in that\nstate by simply going back to an attached state.\n\nSo do a \"s/a list of heads/a list of branch pointers/\" replacement and you\nwill be fine.\n\n> Another example: \"The HEAD then refers to the SHA-1 of the commit \n> instead of to a branch, and git branch shows that you are no longer on a \n> branch:\"  But you *are* on a branch, you just aren't at the head of the \n> branch.\n\nNo, you are _literally_ not on _any_ branch at that point.\n\nMaking a commit from that state does not advance _any_ branch and doing\n\"reset --hard $commit\" from that state does not affect _any_ branch.\n"},{"id":"133070","messageId":"7vvdek70ma.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"b4087cc51001291633l68760880i340d12e865641077@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T03:06:05Z","receivedAt":"2010-01-30T03:06:05Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Witten <mfwitten@gmail.com> writes:\n\n> Isn't the difference between 'checkout' and 'reset' almost essentially\n> a matter of whether the branch reference (HEAD), index, and tree are\n> modified? Couldn't these commands be merged into one command or make\n> use of one command?\n\nI don't think that reduces any confusion.\n\nBy exposing orthogonal options like --index, --head, etc., you are opening\nyourself to nonsensical combinations that were never possible with the\nexisting command set, and I suspect it would make it even more confusing,\nnot less.\n\nWhat does \"git update --detach $commit\" _really_ mean, for example?\n\nYou can of course say \"it detaches the HEAD at $commit, but otherwise does\nnot change anything else\", but such a mechanical description does not give\nan answer that helps end users.  \"What would I do after doing that?\" and\n\"What would I use this for?\" are the questions they need an answer to.\n\nWhat matters is \"after doing this, next commit will record _this_, which\nis often what users want in _that_ situation, and that is why this\ncombination of options makes sense.\"  Do all (or majority) of option\ncombinations to your \"update\" think have _meaning_ in that sense?  I don't\nthink so.\n\nFlexibility and orthogonality is often good, but uncontrolled flexibility\nis not.  And I suspect your \"git update\" is just an uncontrolled mess that\nwould not help users [*1*].\n\n[Footnote]\n\n*1* It is a different matter to have something like that as an ingredient\nto build Porcelain scripts out of.  Porcelain writers may appreciate the\nflexibility and they will choose to use only combinations that make sense\nfor the situation they are trying to deal with.\n"},{"id":"133071","messageId":"alpine.LFD.2.00.1001292208470.1681@xanadu.home","threadId":"22441","inReplyTo":"ca433831001291840o751fa02eve1ae301537674325@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-30T03:11:09Z","receivedAt":"2010-01-30T03:11:09Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Mark Lodato wrote:\n\n> On Fri, Jan 29, 2010 at 8:22 PM, Nicolas Pitre <nico@fluxnic.net> wrote:\n> > On Fri, 29 Jan 2010, Mark Lodato wrote:\n> >\n> >> Still, I find it slightly confusing and unfriendly.  How about the following?\n> >\n> > It is slightly inaccurate.\n> \n> Is the following the only inaccuracy?  Do you have any other feedback?\n> \n> >> Checking out commit 'master^0'.\n> >>\n> >> Since this is not a local branch head, any commits you make will be lost\n> >> when you check out another branch or commit.  (In git terminology, HEAD\n> >> is detached.)  If you just wish to look at files without committing,\n> >> this is fine.  If you wish to make commits and retain them, you may\n> >> create a new branch by running:\n> >>\n> >>   git checkout -b <new_branch_name>\n> >\n> > This gives the impression that any commit you make on a detached HEAD\n> > are going to be lost, unless you create a new branch first.\n> \n> What about \"...you may want to create...\"?  This does not imply that\n> creating a new branch now is the *only* way, just the most likely.  If\n> a user knows another way, that user probably does not need this\n> warning in the first place.\n\nStill, you don't know what way the unsuspected user will take to get \nthere.\n\nDo you still have a problem with the latest version of the text from \nJunio?  Looks like you based your modification on an earlier version.\n\n\nNicolas\n"},{"id":"133073","messageId":"alpine.LFD.2.00.1001292122050.1681@xanadu.home","threadId":"22441","inReplyTo":"alpine.DEB.1.00.1001300312450.3749@intel-tinevez-2-302","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-30T03:15:05Z","receivedAt":"2010-01-30T03:15:05Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Sat, 30 Jan 2010, Johannes Schindelin wrote:\n\n> Hi,\n> \n> On Fri, 29 Jan 2010, Nicolas Pitre wrote:\n> \n> > With all due respects, I don't share Dscho's sentiment about Git's \n> > alleged non user-friendliness.\n> \n> Of course you don't.  You are a Git oldtimer.  Probably you do not even \n> have much exposure to complete programming newbies.\n\nWelllll... That depends.\n\nIf you mean people who, despite a CS degree, are still unable to figure \nout if some loop exit condition should be > or >= except by testing the \ncompiled code and see if a crash occurs, then yes I do feel the pain of \nbeing exposed to such people way too often for my taste.  And frankly I \njust don't care if those people can't grok the Git UI.\n\nGit is meant to be a tool for people performing a minimum of development \ntasks.  If those people can't grasp the Git UI and concepts with little \neffort then they're either 1) uninterested or 2) incompetent.  For the \nuninterested people there are GUIs out there.  And don't get me started \non the incompetent ones.\n\nAnd for the rest of the world, such as my boss, there is gitweb.\n\n> Well, guess what.  I have.  And guess what even more: they are the \n> majority, not you and me.\n\nDid you ever got them to use P4?  I'm convinced that learning how to use \nP4 for a Git user is way more painful than a P4 user to learn Git.  \nSimilarly for Arch or many other alternatives.\n\nHG looks easier?  Sure.  But it isn't exactly as flexible and powerful \nas Git is though.  You prefer a less powerful but simpler tool? OK just \ngo with HG then -- I have no problem with that.  Even SVN might be just \nwhat you need.  But if you prefer the power of Git then there is a price \nto pay for it.  Making Git simpler would inevitably reduces its power.\n\nI hope newbies won't stay newbies all their life.  If the majority of \nall the people are newbies then no need to wonder why there is so much \ncrap being produced by the computing industry then.  Learning isn't only \na nasty thing that they force you to do at school and which you get over \nwith once you escape from there.\n\nIncidentally we've been getting more positive feedback than negative \nones about Git from newbies on this list lately.  That might be because \nour UI, although still not perfect, improved quite a bit, and most \nprobably because the documentation surrounding Git has improved \ntremendously too.\n\n\nNicolas\n"},{"id":"133074","messageId":"ron1-8B7921.19261029012010@news.gmane.org","threadId":"22441","inReplyTo":"7vbpgc8fhb.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-30T03:26:10Z","receivedAt":"2010-01-30T03:26:10Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <7vbpgc8fhb.fsf@alter.siamese.dyndns.org>,\n Junio C Hamano <gitster@pobox.com> wrote:\n\n> Ron Garret <ron1@flownet.com> writes:\n> \n> > 1.  The term \"detached HEAD\" is inherently misleading.  A detached HEAD \n> > isn't detached from anything, it's just pointing to the middle of a \n> > branch, which is to say, to a commit that happens to already have \n> > descendants.  For that matter, the name HEAD is itself misleading, since \n> > HEAD need not be the head of a branch (though normally it is).  A better \n> > name for HEAD would have been CURRENT or ACTIVE.  I recognize it's \n> > probably too late to change it now.\n> \n> This description, especially the phrase \"middle of a branch\" shows that\n> you don't understand git yet.\n\nThat could well be, but it's not for lack of trying :-)\n\n> A git branch is _not_ a line (nor multiple\n> lines) of development.  It is merely a _point_ in the history.\n\nBy \"middle of a branch\" I simply meant \"a commit that already has one or \nmore descendants\" (or, to be even more precise, a commit that has one or \nmore commits that reference that commit as one of their predecessors).  \nI do understand that histories aren't linear.\n\n> \"A commit that is in the middle of an ancestry chain with existing\n> descendants\" can be at the tip of a branch and does not have anything to\n> do with detached HEAD state.\n\nAh, then you're right.  I really don't get it yet.\n\n> When HEAD points at a branch, making a commit advances _that_ branch.  And\n> we say you are \"on that branch\".  When HEAD is detached, because it is not\n> attached to anything, it advances no branch.  \"detached HEAD\" is detached\n> in the very real sense.  It is not attached to _any_ branch.\n\nOK.  The docs do not make that clear at all.  In fact, the following \nstatement, copied straight from the manual, flatly contradicts what you \njust said:\n\n\"The special symbol \"HEAD\" can always be used to refer to the current \nbranch.\"\n\nAlways.  Except when it can't.\n\nSoooo.....\n\nSometimes HEAD can refer to a branch head which is a pointer to a \ncommit, and sometimes HEAD can refer to a commit directly without \nindirecting through a branch head (lower case), in which case it is \ndetached.  Is that right?\n\nIf that's true, then I'm back to wondering what good is a detached head.  \nWhy would you ever want one?  What can you do with a detached head that \nyou could not do just as easily without one?\n\nrg\n"},{"id":"133076","messageId":"ca433831001291959m76ed6adap32a17c10e465af1f@mail.gmail.com","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001292208470.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Mark Lodato","fromEmail":"lodatom@gmail.com","sentAt":"2010-01-30T03:59:49Z","receivedAt":"2010-01-30T03:59:49Z","isPatch":false,"sender":{"key":"lodatom@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58860?v=4"},"body":"On Fri, Jan 29, 2010 at 10:11 PM, Nicolas Pitre <nico@fluxnic.net> wrote:\n> On Fri, 29 Jan 2010, Mark Lodato wrote:\n>> On Fri, Jan 29, 2010 at 8:22 PM, Nicolas Pitre <nico@fluxnic.net> wrote:\n>> > On Fri, 29 Jan 2010, Mark Lodato wrote:\n>> >\n>> >> Still, I find it slightly confusing and unfriendly.  How about the following?\n>> >\n>> >> Checking out commit 'master^0'.\n>> >>\n>> >> Since this is not a local branch head, any commits you make will be lost\n>> >> when you check out another branch or commit.  (In git terminology, HEAD\n>> >> is detached.)  If you just wish to look at files without committing,\n>> >> this is fine.  If you wish to make commits and retain them, you may\n>> >> create a new branch by running:\n>> >>\n>> >>   git checkout -b <new_branch_name>\n>> >\n>> > This gives the impression that any commit you make on a detached HEAD\n>> > are going to be lost, unless you create a new branch first.\n>>\n>> What about \"...you may want to create...\"?  This does not imply that\n>> creating a new branch now is the *only* way, just the most likely.  If\n>> a user knows another way, that user probably does not need this\n>> warning in the first place.\n>\n> Still, you don't know what way the unsuspected user will take to get\n> there.\n\nSorry, I don't understand.  What do you mean by \"take to get there\"?\nAre you referring to how the user arrived in this detached HEAD state,\nor what the user wishes to do next?  Either way, I still am not sure\nwhy this wording is no good.  Could please elaborate?\n\n> Do you still have a problem with the latest version of the text from\n> Junio?  Looks like you based your modification on an earlier version.\n\nYes, I do.  I thought his earlier version was more clear.  Particularly:\n\n  Note: 'master^0' isn't a local branch head;\n\nThis isn't very friendly.  It sounds like an admonition.  Rather, I\nsuggest that the first sentence be similar to, but distinct from,\n\"Switched to branch foo,\" to inform the user that they did something\ndifferent, which may or may not be intentional.\n\n  You are in 'detached HEAD' state. You can look around, make experimental\n  changes and commit them, and you can discard any commits you make in this\n  state without impacting any branches by checking out another branch.\n\nFirst, we shouldn't start off with the term \"detached HEAD\".  I used a\nparenthetical comment to mention it, in case the user wants to look it\nup or refer to this state.  Otherwise, the term conveys no meaning,\nunless one understand enough about git to not need this advice.\n\nSecond, this advice should be a warning that commits may be lost\nunless one knows what one is doing.  Saying \"you can discard commits\"\nmakes it sound like a feature!  Sure, that may be so for advanced\nusers, but for beginners (for whom this advice is intended), this is a\ncommon trap.  I tried to word the advice so that the users will know\nthat they should not commit without first creating a branch (or\nknowing what they're doing), but that if they don't commit, there's no\nproblem.  The wording quoted above does not convey this meaning to me.\n\n  If you want to create a new branch to retain commits you create, you may\n  do so (now or later) by using -b with the checkout command again. Example:\n\n    git checkout -b <new_branch_name>\n\nI basically retained this, with rewording.\n\n\nThis discussion brings up another good point: The main worry about a\ndetached head is losing commits.  Back in 2008, it was suggested to\nhave a warning when committing on a detached HEAD:\n\nhttp://kerneltrap.org/mailarchive/git/2008/9/2/3169744\n\nThis was before the advice system, so folks complained about it\ngetting in the way, and it was never implemented.  Since we now have a\nway to easily turn off the warning, perhaps we should bring this topic\nup again (probably as a separate thread.)\n"},{"id":"133077","messageId":"alpine.LFD.2.00.1001292232130.1681@xanadu.home","threadId":"22441","inReplyTo":"ron1-8B7921.19261029012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-30T04:03:25Z","receivedAt":"2010-01-30T04:03:25Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Ron Garret wrote:\n\n> In article <7vbpgc8fhb.fsf@alter.siamese.dyndns.org>,\n>  Junio C Hamano <gitster@pobox.com> wrote:\n> \n> > \"A commit that is in the middle of an ancestry chain with existing\n> > descendants\" can be at the tip of a branch and does not have anything to\n> > do with detached HEAD state.\n> \n> Ah, then you're right.  I really don't get it yet.\n\nHave a look at http://eagain.net/articles/git-for-computer-scientists/\n\nThat's one of the clearest explanation of the Git branching model I've \nseen.\n\n> > When HEAD points at a branch, making a commit advances _that_ branch.  And\n> > we say you are \"on that branch\".  When HEAD is detached, because it is not\n> > attached to anything, it advances no branch.  \"detached HEAD\" is detached\n> > in the very real sense.  It is not attached to _any_ branch.\n> \n> OK.  The docs do not make that clear at all.  In fact, the following \n> statement, copied straight from the manual, flatly contradicts what you \n> just said:\n> \n> \"The special symbol \"HEAD\" can always be used to refer to the current \n> branch.\"\n> \n> Always.  Except when it can't.\n\nThere is no contradiction.  The \"detached HEAD\" corresponds to HEAD \npointing at no branch in particular.  There is just no current branch in \nthat case.\n\n> Soooo.....\n> \n> Sometimes HEAD can refer to a branch head which is a pointer to a \n> commit, and sometimes HEAD can refer to a commit directly without \n> indirecting through a branch head (lower case), in which case it is \n> detached.  Is that right?\n\nExact.\n\n> If that's true, then I'm back to wondering what good is a detached head.  \n> Why would you ever want one?  What can you do with a detached head that \n> you could not do just as easily without one?\n\nBy definition, remote tracking branches are \"read-only\" because we want \nthose branch heads to reflect what the remote repository they're \ntracking has.  In other words, you're not supposed to add commits to a \nremote branch or it would move that branch to the new commit which is no \nlonger a representation of the corresponding remote repository.  In \norder to actually add commits on top of a remote branch, you first have \nto make a local branch being a copy of the remote branch of interest \n(which in practice means only making the local branch point at the same \ncommit node as the remote branch) and then any commit will advance that \nlocal branch and leave the remote branch behind.\n\nBut what if you just want to check out the content corresponding to that \nremote branch without adding any new commits?  What if you wish to do \nthe same with a tag instead of a branch (a tag being immutable)?\n\nIf you could have HEAD pointing to a tag or a remote branch then many \noperations such as 'git commit' would need to be blocked in order to \npreserve the read-only nature of such references.\n\nThe detached HEAD solves the issue really neatly in those cases.  \nInstead of having HEAD pointing to a remote branch record, the detached \nHEAD points directly at the provided commit from the remote branch head \nor tag, and any commit operation will simply update that direct \nreference alone, creating a fork point in the history graph.\n\nIf you wish to preserve this branch in the graph sense then you can \ncreate a new branch head with the current HEAD position.  Or if you \ndon't care about those commits you made on the detached HEAD, then \nsimply moving HEAD to anything else with another checkout command will \ndrop and forget about that string of commits you created.\n\nSo a detached HEAD is useful for checking out a read-only branch or tag \nwithout having to forbid a bunch of operations or needing for you to \ncreate a dummy temporary local branch just for the purpose of such a \ncheckout.  Many operations with intermediate states such as 'git rebase' \nor 'git bisect' can be implemented without polluting the branch \nnamespace, etc.\n\n\nNicolas\n"},{"id":"133078","messageId":"alpine.LFD.2.00.1001292305500.1681@xanadu.home","threadId":"22441","inReplyTo":"ca433831001291959m76ed6adap32a17c10e465af1f@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-30T04:39:25Z","receivedAt":"2010-01-30T04:39:25Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Mark Lodato wrote:\n\n> On Fri, Jan 29, 2010 at 10:11 PM, Nicolas Pitre <nico@fluxnic.net> wrote:\n> > On Fri, 29 Jan 2010, Mark Lodato wrote:\n> >> On Fri, Jan 29, 2010 at 8:22 PM, Nicolas Pitre <nico@fluxnic.net> wrote:\n> >> > On Fri, 29 Jan 2010, Mark Lodato wrote:\n> >> >\n> >> >> Still, I find it slightly confusing and unfriendly.  How about the following?\n> >> >\n> >> >> Checking out commit 'master^0'.\n> >> >>\n> >> >> Since this is not a local branch head, any commits you make will be lost\n> >> >> when you check out another branch or commit.  (In git terminology, HEAD\n> >> >> is detached.)  If you just wish to look at files without committing,\n> >> >> this is fine.  If you wish to make commits and retain them, you may\n> >> >> create a new branch by running:\n> >> >>\n> >> >>   git checkout -b <new_branch_name>\n> >> >\n> >> > This gives the impression that any commit you make on a detached HEAD\n> >> > are going to be lost, unless you create a new branch first.\n> >>\n> >> What about \"...you may want to create...\"?  This does not imply that\n> >> creating a new branch now is the *only* way, just the most likely.  If\n> >> a user knows another way, that user probably does not need this\n> >> warning in the first place.\n> >\n> > Still, you don't know what way the unsuspected user will take to get\n> > there.\n> \n> Sorry, I don't understand.  What do you mean by \"take to get there\"?\n> Are you referring to how the user arrived in this detached HEAD state,\n\nYes.\n\n> or what the user wishes to do next?  Either way, I still am not sure\n> why this wording is no good.  Could please elaborate?\n\nFirst, I'm afraid that \"Checking out commit 'foobar'\" might be confusing \nas this may happen through either a remote branch, a tag, or any random \ncommit.  It seems to me that \"Checking out 'v2.5'\" is less confusing \nthan \"Checking out commit 'v2.5'\".  But that's a minor detail and \nprobably a personal preference.\n\n>   Note: 'master^0' isn't a local branch head;\n> \n> This isn't very friendly.  It sounds like an admonition.  Rather, I\n> suggest that the first sentence be similar to, but distinct from,\n> \"Switched to branch foo,\" to inform the user that they did something\n> different, which may or may not be intentional.\n\nI consider that starting the explanation paragraph with \" any commits \nyou make will be lost\" is even more unfriendly, and misleading.  That is \nsure to scare people needlessly.\n\n>   You are in 'detached HEAD' state. You can look around, make experimental\n>   changes and commit them, and you can discard any commits you make in this\n>   state without impacting any branches by checking out another branch.\n> \n> First, we shouldn't start off with the term \"detached HEAD\".  I used a\n> parenthetical comment to mention it, in case the user wants to look it\n> up or refer to this state.  Otherwise, the term conveys no meaning,\n> unless one understand enough about git to not need this advice.\n\nTo the contrary: this \"detached HEAD\" is exactly what you need if you \nwant to relate to any documentation or perform a search for more \ninformation.  Like it or not, this detached HEAD term is exactly what \nthis Git concept is all about and how it is designated everywhere.  The \nsooner Git users see and learn about it the better.\n\n> Second, this advice should be a warning that commits may be lost\n> unless one knows what one is doing.  Saying \"you can discard commits\"\n> makes it sound like a feature!  Sure, that may be so for advanced\n> users, but for beginners (for whom this advice is intended), this is a\n> common trap.  I tried to word the advice so that the users will know\n> that they should not commit without first creating a branch (or\n> knowing what they're doing), but that if they don't commit, there's no\n> problem.  The wording quoted above does not convey this meaning to me.\n\nI think your wording is just too far on the negative side, and makes Git \nlook like an even more difficult tool than it actually is.  And you help \nno one by stating things that are not exactly true even if the truth \nimplies that you need to know what you're doing.  The _whole_ and only \npoint of a detached HEAD is actually to be able to make commits even \nwithout having to create a new branch first.\n\n> This discussion brings up another good point: The main worry about a\n> detached head is losing commits.  Back in 2008, it was suggested to\n> have a warning when committing on a detached HEAD:\n> \n> http://kerneltrap.org/mailarchive/git/2008/9/2/3169744\n> \n> This was before the advice system, so folks complained about it\n> getting in the way, and it was never implemented.  Since we now have a\n> way to easily turn off the warning, perhaps we should bring this topic\n> up again (probably as a separate thread.)\n\nPossibly.  I don't like the message proposed in that patch though.  \nSince the warning when actually detaching HEAD is about to become way \nmore prominent, the per-commit warning doesn't have to be that noisy \nanymore.\n\n\nNicolas\n"},{"id":"133079","messageId":"76718491001292052x7f46d479lfeff7b66121502c3@mail.gmail.com","threadId":"22441","inReplyTo":"7vbpgc8fhb.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2010-01-30T04:52:18Z","receivedAt":"2010-01-30T04:52:18Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Fri, Jan 29, 2010 at 9:59 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Ron Garret <ron1@flownet.com> writes:\n>\n>> 1.  The term \"detached HEAD\" is inherently misleading.  A detached HEAD\n>> isn't detached from anything, it's just pointing to the middle of a\n>> branch, which is to say, to a commit that happens to already have\n>> descendants.  For that matter, the name HEAD is itself misleading, since\n>> HEAD need not be the head of a branch (though normally it is).  A better\n>> name for HEAD would have been CURRENT or ACTIVE.  I recognize it's\n>> probably too late to change it now.\n>\n> This description, especially the phrase \"middle of a branch\" shows that\n> you don't understand git yet.  A git branch is _not_ a line (nor multiple\n> lines) of development.  It is merely a _point_ in the history.\n>\n> \"A commit that is in the middle of an ancestry chain with existing\n> descendants\" can be at the tip of a branch and does not have anything to\n> do with detached HEAD state.\n>\n> When HEAD points at a branch, making a commit advances _that_ branch.  And\n> we say you are \"on that branch\".  When HEAD is detached, because it is not\n> attached to anything, it advances no branch.  \"detached HEAD\" is detached\n> in the very real sense.  It is not attached to _any_ branch.\n\nLet me try wording this slightly different, because I think I can see\nRon's confusion.\n\nHEAD normally refers to a named branch. For example \"master\"\n(technically, HEAD would contain \"ref: refs/heads/master\"), but we'll\njust say \"master\" for now.\n\nMeanwhile, the branch named \"master\" refers to a specific commit by\nits SHA-1 hash.\n\nThe particular commit which \"master\" refers to is a branch head.\n\nNow, when you create a commit in this state, the branch named \"master\"\nis updated with the SHA-1 of the new commit. So let's say you create a\nnew repo and have three commits. Your history would look like this:\n\na---b---c master (HEAD is \"ref: refs/heads/master\")\n\nThat is, if you look at .git/HEAD, it will say \"ref:\nrefs/heads/master\" and if you look at .git/refs/heads/master it will\nhave the SHA-1 of commit \"c\". If you create a new commit:\n\na---b---c---d master (HEAD is \"ref: refs/heads/master\")\n\n.git/HEAD still says \"ref: refs/heads/master\" but now\n.git/refs/heads/master has the SHA-1 of commit \"d\".\n\nOkay, now let's talk about what happens when you type:\n\n$ git checkout master^\n\nAt this point, git updates HEAD to contain the SHA-1 of \"c\":\n\na---b---c---d master (HEAD is c's SHA-1)\n\nYou now have a \"detached HEAD\" because HEAD doesn't refer to any named\nbranch. Instead it refers to a specific commit by its SHA-1. So let's\ncreate a new commit while HEAD is detached:\n\na---b---c---d master\n         \\\n          e   (HEAD is e's SHA-1)\n\nSo, yes, you've created a \"branch\" in the DAG sense of the word. But\nthis branch is anonymous since it has no name. That means that commit\n\"e\" is subject to garbage collection and may be removed. If you want\nto keep it around, then you need to create a name for it. Git provides\nyou a number of ways to \"name\" commits:\n\n$ git checkout -b foo # (1)\n$ git branch foo      # (2)\n$ git tag foo         # (3)\n\n(1) will create .git/refs/heads/foo, make it have the SHA-1 of commit\n\"e\", then update HEAD to say \"ref: refs/heads/foo\". You are now \"on\"\nbranch \"foo\" and any commits you create will update\n.git/refs/heads/foo:\n\na---b---c---d master\n         \\\n          e  foo (HEAD is \"ref: refs/heads/foo\")\n\n(2) will also create .refs/heads/foo, and make it have the SHA-1 of\ncommit \"e\", but will leave HEAD as it is:\n\na---b---c---d master\n         \\\n          e  foo (HEAD is SHA-1 of \"e\")\n\nYou still have a detached HEAD and any commits you create that descend\nfrom \"e\" are still subject to garbage collection (although \"e\" itself\nis not), as follows:\n\na---b---c---d master\n         \\\n          e  <-- foo\n           \\\n            f (HEAD is SHA-1 of \"f\")\n\n(3) creates .refs/tags/foo, but is otherwise the same as (2).\n\nSo that was a really long explanation, but I hope it clears things up.\nI think the disconnect between you and Junio is that you're thinking\nof branches in the DAG sense of the word, while Junio is talking about\nthem in the context of git.\n\nj.\n"},{"id":"133080","messageId":"alpine.LFD.2.00.1001292352540.1681@xanadu.home","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001292305500.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-30T05:05:45Z","receivedAt":"2010-01-30T05:05:45Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Nicolas Pitre wrote:\n\n> On Fri, 29 Jan 2010, Mark Lodato wrote:\n> \n> > This discussion brings up another good point: The main worry about a\n> > detached head is losing commits.  Back in 2008, it was suggested to\n> > have a warning when committing on a detached HEAD:\n> > \n> > http://kerneltrap.org/mailarchive/git/2008/9/2/3169744\n> > \n> > This was before the advice system, so folks complained about it\n> > getting in the way, and it was never implemented.  Since we now have a\n> > way to easily turn off the warning, perhaps we should bring this topic\n> > up again (probably as a separate thread.)\n> \n> Possibly.  I don't like the message proposed in that patch though.  \n> Since the warning when actually detaching HEAD is about to become way \n> more prominent, the per-commit warning doesn't have to be that noisy \n> anymore.\n\nThinking more about it, I still consider that making 'git commit' more \nnoisy is the wrong approach.  Again, the problem is not about making \ncommits on a detached HEAD.  but rather about losing those commits at \nthe next 'git checkout'.  Probably a warning should be made when that \ncheckout is attempted after one or more commits were made on a detached \nHEAD instead, and refuse the checkout by default unless it is forced (-f \nis already taken for some other force meaning).  The warning should say \nhow not to lose those commits by suggesting a branch creation, or give \nthe hint for performing the checkout anyway.\n\n\nNicolas\n"},{"id":"133081","messageId":"76718491001292106je41d6e4x7341678c475122db@mail.gmail.com","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001292232130.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2010-01-30T05:06:40Z","receivedAt":"2010-01-30T05:06:40Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Fri, Jan 29, 2010 at 11:03 PM, Nicolas Pitre <nico@fluxnic.net> wrote:\n> Have a look at http://eagain.net/articles/git-for-computer-scientists/\n>\n> That's one of the clearest explanation of the Git branching model I've\n> seen.\n\nAh, I never realized this before, but it doesn't include any\ndiscussion/graphic of what a detached HEAD is. It only shows HEAD\nreferring to a named branch.\n\n> There is no contradiction.  The \"detached HEAD\" corresponds to HEAD\n> pointing at no branch in particular.  There is just no current branch in\n> that case.\n\nAgain (referring to my last message), I think Ron's confusion is that\n\"branch\" can mean either a branch in the DAG which is your repo's\nhistory, or it can mean a named branch (something under .git/refs),\nand they aren't necessarily the same, although around here when we say\n\"branch\" we almost always mean a named branch.\n\nWhen HEAD is detached and you create a commit, you're effectively\ncreating a branch in the DAG, but this branch is anonymous and subject\nto garbage collection.\n\nj.\n"},{"id":"133082","messageId":"7vk4v041r1.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"ron1-8B7921.19261029012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T05:09:54Z","receivedAt":"2010-01-30T05:09:54Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ron Garret <ron1@flownet.com> writes:\n\n>> When HEAD points at a branch, making a commit advances _that_ branch.  And\n>> we say you are \"on that branch\".  When HEAD is detached, because it is not\n>> attached to anything, it advances no branch.  \"detached HEAD\" is detached\n>> in the very real sense.  It is not attached to _any_ branch.\n>\n> OK.  The docs do not make that clear at all.  In fact, the following \n> statement, copied straight from the manual, flatly contradicts what you \n> just said:\n\nThere are many places in the documentation that simply predate the\nintroduction of detached HEAD.  The description talks as if you cannot be\nin any state other than on a particular branch.  For example, \"git pull\"\ntalks about choosing where to fetch from and what to merge to the head\nbased on what your current branch is---obviously such a description is\nancient and doesn't talk about what should happen when you do not simply\nhave any \"current\" branch.\n\nSo it is understandable that you get confused and it is all\ndocumentation's fault, not yours.\n\n> \"The special symbol \"HEAD\" can always be used to refer to the current \n> branch.\"\n>\n> Always.  Except when it can't.\n\nExactly.\n\nWe would need to update the documentation.  While doing so, a general\nguideline would be to keep in mind that they were written back when you\nhad to always be on _a_ branch (and they called it \"current branch\",\n\"branch HEAD points at\", etc.).  When they describe that \"the current\nbranch is updated in such and such way\", what happens in a detached HEAD\nstate is that only the HEAD pointer that directly points at the \"currently\nchecked out commit\" is updated, without affecting _any_ branch.\n"},{"id":"133083","messageId":"76718491001292111y2d15620ei8a12c081a9283a07@mail.gmail.com","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001292352540.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2010-01-30T05:11:55Z","receivedAt":"2010-01-30T05:11:55Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Sat, Jan 30, 2010 at 12:05 AM, Nicolas Pitre <nico@fluxnic.net> wrote:\n> Thinking more about it, I still consider that making 'git commit' more\n> noisy is the wrong approach.  Again, the problem is not about making\n> commits on a detached HEAD.  but rather about losing those commits at\n> the next 'git checkout'.  Probably a warning should be made when that\n> checkout is attempted after one or more commits were made on a detached\n> HEAD instead, and refuse the checkout by default unless it is forced (-f\n> is already taken for some other force meaning).  The warning should say\n> how not to lose those commits by suggesting a branch creation, or give\n> the hint for performing the checkout anyway.\n\nThis sounds right to me too. There's nothing wrong with having a\ndetached HEAD, and nothing wrong with creating commits in that state.\nYou're effectively creating an anonymous branch in the DAG and it's\nsubject to garbage collection if you move away from that anonymous\nbranch w/o naming it.\n\nPedantic note: you don't lose those commits at the next checkout. They\nare merely subject to garbage collection (and not until they age out\nof HEAD's reflog). I know you know that, just being precise. :-)\n\nj.\n"},{"id":"133084","messageId":"alpine.LFD.2.00.1001300011290.1681@xanadu.home","threadId":"22441","inReplyTo":"76718491001292052x7f46d479lfeff7b66121502c3@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-30T05:15:06Z","receivedAt":"2010-01-30T05:15:06Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 29 Jan 2010, Jay Soffian wrote:\n\n> > When HEAD points at a branch, making a commit advances _that_ branch.  And\n> > we say you are \"on that branch\".  When HEAD is detached, because it is not\n> > attached to anything, it advances no branch.  \"detached HEAD\" is detached\n> > in the very real sense.  It is not attached to _any_ branch.\n> \n> Let me try wording this slightly different, because I think I can see\n> Ron's confusion.\n[...]\n\nCould you please take this really nice explanation and make it into a \npatch adding a \"Detached HEAD\" section in the git-checkout.txt manual \npage please?\n\n\nNicolas\n"},{"id":"133085","messageId":"7v7hr041cc.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"76718491001292052x7f46d479lfeff7b66121502c3@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T05:18:43Z","receivedAt":"2010-01-30T05:18:43Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jay Soffian <jaysoffian@gmail.com> writes:\n\n> So that was a really long explanation, but I hope it clears things up.\n> I think the disconnect between you and Junio is that you're thinking\n> of branches in the DAG sense of the word, while Junio is talking about\n> them in the context of git.\n\nYeah, in short, a \"branch\" is a point, not a line (or lines) of\ndevelopment that leads to a point, as I said in the beginning.\n"},{"id":"133086","messageId":"7v1vh8417w.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001300011290.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T05:21:23Z","receivedAt":"2010-01-30T05:21:23Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@fluxnic.net> writes:\n\n> Could you please take this really nice explanation and make it into a \n> patch adding a \"Detached HEAD\" section in the git-checkout.txt manual \n> page please?\n\nGood suggestion.\n\nI'd be happier if the description didn't say \"SHA-1\", but instead said\n\"object name\".\n\nAlso it would be nicer (just a personal preference) if a picture that\nforks only one branch forks it upwards, like this:\n\n             o---o\n            /    \n    ---o---o---o\n\nnot downwards, like this:\n\n    ---o---o---o\n            \\\n             o---o\n"},{"id":"133087","messageId":"alpine.LFD.2.00.1001300018040.1681@xanadu.home","threadId":"22441","inReplyTo":"76718491001292111y2d15620ei8a12c081a9283a07@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Nicolas Pitre","fromEmail":"nico@fluxnic.net","sentAt":"2010-01-30T05:25:14Z","receivedAt":"2010-01-30T05:25:14Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Sat, 30 Jan 2010, Jay Soffian wrote:\n\n> This sounds right to me too. There's nothing wrong with having a\n> detached HEAD, and nothing wrong with creating commits in that state.\n> You're effectively creating an anonymous branch in the DAG and it's\n> subject to garbage collection if you move away from that anonymous\n> branch w/o naming it.\n> \n> Pedantic note: you don't lose those commits at the next checkout. They\n> are merely subject to garbage collection (and not until they age out\n> of HEAD's reflog). I know you know that, just being precise. :-)\n\nBeing the actual author of the code managing the separate HEAD reflog, I \ndo know that indeed.  ;-)\n\n\nNicolas\n"},{"id":"133088","messageId":"76718491001292145y3d31ecc9y9b180ec89587288f@mail.gmail.com","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001300011290.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2010-01-30T05:45:58Z","receivedAt":"2010-01-30T05:45:58Z","isPatch":false,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Sat, Jan 30, 2010 at 12:15 AM, Nicolas Pitre <nico@fluxnic.net> wrote:\n> Could you please take this really nice explanation and make it into a\n> patch adding a \"Detached HEAD\" section in the git-checkout.txt manual\n> page please?\n\nWill do, and I'll even make the branches go upwards. :-)\n\nj.\n"},{"id":"133089","messageId":"ca433831001292153idee3677gf9761d9726dca135@mail.gmail.com","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001292305500.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Mark Lodato","fromEmail":"lodatom@gmail.com","sentAt":"2010-01-30T05:53:47Z","receivedAt":"2010-01-30T05:53:47Z","isPatch":false,"sender":{"key":"lodatom@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58860?v=4"},"body":"On Fri, Jan 29, 2010 at 11:39 PM, Nicolas Pitre <nico@fluxnic.net> wrote:\n> First, I'm afraid that \"Checking out commit 'foobar'\" might be confusing\n> as this may happen through either a remote branch, a tag, or any random\n> commit.  It seems to me that \"Checking out 'v2.5'\" is less confusing\n> than \"Checking out commit 'v2.5'\".  But that's a minor detail and\n> probably a personal preference.\n\nI'm fine with \"Checking out 'v2.5'\".\n\n> I consider that starting the explanation paragraph with \" any commits\n> you make will be lost\" is even more unfriendly, and misleading.  That is\n> sure to scare people needlessly.\n\nSee wording below.\n\n> I think your wording is just too far on the negative side, and makes Git\n> look like an even more difficult tool than it actually is.  And you help\n> no one by stating things that are not exactly true even if the truth\n> implies that you need to know what you're doing.\n\nWhat is not true?  Sure, they're not really \"lost\", but there's no\nconcise yet fully correct way to say the full truth.  Would you prefer\n\"discarded\"?\n\n> The _whole_ and only\n> point of a detached HEAD is actually to be able to make commits even\n> without having to create a new branch first.\n\nWrong.  I have never (purposefully) made a commit on a detached HEAD,\nyet I use a detached HEAD all the time.  Why?  Because I checkout a\nparticular commit to look at code at a given location.  For example, I\nrecently ran \"git checkout v1.6.6.1\".  I did not intend to make any\ncommits on this; I just wanted to look at and compile code at a\nparticular version.  I think most users do the same thing.  The reason\nfor the warning is that folks make a mistake of trying to commit\nwithout first switching back to (or creating) a branch.\n\n\nAnyway, how about the following message, which is more in line with\nJunio's last version?\n\n-- >8 -- not a patch -- >8 --\nChecking out 'master^0'.\n\nThis is not a local branch head, so you are in a 'detached HEAD' state.\nIf you only plan to look at files, this is fine.  However, any commits you\nmake will not update a branch, and may be discarded when you check out\nanother branch or commit.\n\nIf you want to create a new branch to retain commits you create, you may\ndo so (now or later) by using -b with the checkout command again. Example:\n\n git checkout -b <new_branch_name>\n\nHEAD is now at a9d7c95... Merge branch 'maint'\n-- 8< -- not a patch -- 8< --\n"},{"id":"133090","messageId":"7v8wbg2kpf.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001292305500.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T06:03:24Z","receivedAt":"2010-01-30T06:03:24Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@fluxnic.net> writes:\n\n> First, I'm afraid that \"Checking out commit 'foobar'\" might be confusing \n> as this may happen through either a remote branch, a tag, or any random \n> commit.  It seems to me that \"Checking out 'v2.5'\" is less confusing \n> than \"Checking out commit 'v2.5'\".  But that's a minor detail and \n> probably a personal preference.\n> ...\n> To the contrary: this \"detached HEAD\" is exactly what you need if you \n> want to relate to any documentation or perform a search for more \n> information.  Like it or not, this detached HEAD term is exactly what \n> this Git concept is all about and how it is designated everywhere.  The \n> sooner Git users see and learn about it the better.\n\nAs I am not good at keeping track of different proposals to change this\nword here and that word there, I expect this will probably need at least\nfew rotations of earth to get input from people in different timezones,\nand I think this is post 1.7.0 item anyway, I'll queue the attached draft\nin 'pu' and keep it there, to make it easier for others to tweak the\nmessage.\n\n-- >8 --\nSubject: [PATCH] Reword \"detached HEAD\" notification\n\nThe old \"advice\" message explained how to create a branch after going into\na detached HEAD state but didn't make it clear why the user may want to do\nso.  Also \"moving to ... which isn't a local branch\" was unclear if it is\ncomplaining, if it is describing the new state, or if it is explaining why\nthe HEAD is detached (the true reason is the last one).\n\nGive the established phrase 'detached HEAD' first to make it easy for\nusers to look up the concept in documentation, and briefly describe what\ncan be done in the state (i.e. play around without having to clean up)\nbefore telling the user how to keep what was done during the temporary\nstate.\n\nAllow the long description to be hidden by setting advice.detachedHead\nconfiguration to false.\n\nWe might want to customize the advice depending on how the commit to check\nout was spelled (e.g. instead of \"new-branch-name\", we way want to say\n\"topic\" when \"git checkout origin/topic\" triggered this message) in later\nupdates, but this encapsulates that into a separate function and it should\nbe a good first step.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/config.txt |    5 +++++\n advice.c                 |    2 ++\n advice.h                 |    1 +\n builtin-checkout.c       |   18 ++++++++++++++++--\n t/t7201-co.sh            |   32 ++++++++++++++++++++++----------\n 5 files changed, 46 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/config.txt b/Documentation/config.txt\nindex 17901e2..fee44d8 100644\n--- a/Documentation/config.txt\n+++ b/Documentation/config.txt\n@@ -138,6 +138,11 @@ advice.*::\n \t\tAdvice on how to set your identity configuration when\n \t\tyour information is guessed from the system username and\n \t\tdomain name. Default: true.\n+\n+\tdetachedHead::\n+\t\tAdvice shown when you used linkgit::git-checkout[1] to\n+\t\tmove to the detach HEAD state, to instruct how to create\n+\t\ta local branch after the fact.  Default: true.\n --\n \n core.fileMode::\ndiff --git a/advice.c b/advice.c\nindex 936d98b..0be4b5f 100644\n--- a/advice.c\n+++ b/advice.c\n@@ -5,6 +5,7 @@ int advice_status_hints = 1;\n int advice_commit_before_merge = 1;\n int advice_resolve_conflict = 1;\n int advice_implicit_identity = 1;\n+int advice_detached_head = 1;\n \n static struct {\n \tconst char *name;\n@@ -15,6 +16,7 @@ static struct {\n \t{ \"commitbeforemerge\", &advice_commit_before_merge },\n \t{ \"resolveconflict\", &advice_resolve_conflict },\n \t{ \"implicitidentity\", &advice_implicit_identity },\n+\t{ \"detachedhead\", &advice_detached_head },\n };\n \n int git_default_advice_config(const char *var, const char *value)\ndiff --git a/advice.h b/advice.h\nindex 9b7a3ad..3244ebb 100644\n--- a/advice.h\n+++ b/advice.h\n@@ -8,6 +8,7 @@ extern int advice_status_hints;\n extern int advice_commit_before_merge;\n extern int advice_resolve_conflict;\n extern int advice_implicit_identity;\n+extern int advice_detached_head;\n \n int git_default_advice_config(const char *var, const char *value);\n \ndiff --git a/builtin-checkout.c b/builtin-checkout.c\nindex 5277817..c5ab783 100644\n--- a/builtin-checkout.c\n+++ b/builtin-checkout.c\n@@ -488,6 +488,20 @@ static void report_tracking(struct branch_info *new)\n \tstrbuf_release(&sb);\n }\n \n+static void detach_advice(const char *old_path, const char *new_name)\n+{\n+\tconst char fmt[] =\n+\t\"Note: checking out '%s'.\\n\\n\"\n+\t\"You are in 'detached HEAD' state. You can look around, make experimental\\n\"\n+\t\"changes and commit them, and you can discard any commits you make in this\\n\"\n+\t\"state without impacting any branches by performing another checkout.\\n\\n\"\n+\t\"If you want to create a new branch to retain commits you create, you may\\n\"\n+\t\"do so (now or later) by using -b with the checkout command again. Example:\\n\\n\"\n+\t\"  git checkout -b new_branch_name\\n\\n\";\n+\n+\tfprintf(stderr, fmt, new_name);\n+}\n+\n static void update_refs_for_switch(struct checkout_opts *opts,\n \t\t\t\t   struct branch_info *old,\n \t\t\t\t   struct branch_info *new)\n@@ -522,8 +536,8 @@ static void update_refs_for_switch(struct checkout_opts *opts,\n \t\tupdate_ref(msg.buf, \"HEAD\", new->commit->object.sha1, NULL,\n \t\t\t   REF_NODEREF, DIE_ON_ERR);\n \t\tif (!opts->quiet) {\n-\t\t\tif (old->path)\n-\t\t\t\tfprintf(stderr, \"Note: moving to '%s' which isn't a local branch\\nIf you want to create a new branch from this checkout, you may do so\\n(now or later) by using -b with the checkout command again. Example:\\n  git checkout -b <new_branch_name>\\n\", new->name);\n+\t\t\tif (old->path && advice_detached_head)\n+\t\t\t\tdetach_advice(old->path, new->name);\n \t\t\tdescribe_detached_head(\"HEAD is now at\", new->commit);\n \t\t}\n \t}\ndiff --git a/t/t7201-co.sh b/t/t7201-co.sh\nindex 6442f71..d20ed61 100755\n--- a/t/t7201-co.sh\n+++ b/t/t7201-co.sh\n@@ -166,19 +166,31 @@ test_expect_success 'checkout -m with merge conflict' '\n \t! test -s current\n '\n \n-test_expect_success 'checkout to detach HEAD' '\n+test_expect_success 'checkout to detach HEAD (with advice declined)' '\n \n+\tgit config advice.detachedHead false &&\n \tgit checkout -f renamer && git clean -f &&\n \tgit checkout renamer^ 2>messages &&\n-\t(cat >messages.expect <<EOF\n-Note: moving to '\\''renamer^'\\'' which isn'\\''t a local branch\n-If you want to create a new branch from this checkout, you may do so\n-(now or later) by using -b with the checkout command again. Example:\n-  git checkout -b <new_branch_name>\n-HEAD is now at 7329388... Initial A one, A two\n-EOF\n-) &&\n-\ttest_cmp messages.expect messages &&\n+\tgrep \"HEAD is now at 7329388\" messages &&\n+\ttest 1 -eq $(wc -l <messages) &&\n+\tH=$(git rev-parse --verify HEAD) &&\n+\tM=$(git show-ref -s --verify refs/heads/master) &&\n+\ttest \"z$H\" = \"z$M\" &&\n+\tif git symbolic-ref HEAD >/dev/null 2>&1\n+\tthen\n+\t\techo \"OOPS, HEAD is still symbolic???\"\n+\t\tfalse\n+\telse\n+\t\t: happy\n+\tfi\n+'\n+\n+test_expect_success 'checkout to detach HEAD' '\n+\tgit config advice.detachedHead true &&\n+\tgit checkout -f renamer && git clean -f &&\n+\tgit checkout renamer^ 2>messages &&\n+\tgrep \"HEAD is now at 7329388\" messages &&\n+\ttest 1 -lt $(wc -l <messages) &&\n \tH=$(git rev-parse --verify HEAD) &&\n \tM=$(git show-ref -s --verify refs/heads/master) &&\n \ttest \"z$H\" = \"z$M\" &&\n-- \n1.7.0.rc0.187.g226c\n"},{"id":"133091","messageId":"ron1-FA4289.22165129012010@news.gmane.org","threadId":"22441","inReplyTo":"7vvdek70ma.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-30T06:16:51Z","receivedAt":"2010-01-30T06:16:51Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <7vvdek70ma.fsf@alter.siamese.dyndns.org>,\n Junio C Hamano <gitster@pobox.com> wrote:\n\n> Michael Witten <mfwitten@gmail.com> writes:\n> \n> > Isn't the difference between 'checkout' and 'reset' almost essentially\n> > a matter of whether the branch reference (HEAD), index, and tree are\n> > modified? Couldn't these commands be merged into one command or make\n> > use of one command?\n> \n> I don't think that reduces any confusion.\n\nAhem... as the confused one here I respectfully disagree.\n\n> By exposing orthogonal options like --index, --head, etc., you are opening\n> yourself to nonsensical combinations that were never possible with the\n> existing command set, and I suspect it would make it even more confusing,\n> not less.\n\nNo, because it would make it much easier to map intent back into a \ncommand that implements that intent.  Don't forget, this whole thing \nbegan because I wanted to do something very simple, tried what seemed to \nbe the obvious way to do it, and stumbled accidentally on an advanced \nfeature.  That would not have happened if I'd been able to just do a git \nupdate --tree master^.\n\n> What does \"git update --detach $commit\" _really_ mean, for example?\n\nWhat difference does that make?  Sure, there would be ways to shoot \nyourself in the foot with git update, but there is no shortage of ways \nto shoot yourself in the foot now.  And now if you shoot yourself in the \nfoot you have to start by trying to figure out where the bullet came \nfrom.\n\nBTW, nothing prevents you from providing the usual repertoire of \nhigher-level functionality as thin layers on top of something like git \nupdate.\n\n> You can of course say \"it detaches the HEAD at $commit, but otherwise does\n> not change anything else\", but such a mechanical description does not give\n> an answer that helps end users.  \"What would I do after doing that?\" and\n> \"What would I use this for?\" are the questions they need an answer to.\n\nSure.  So document the combinations that make sense, and then say \"You \ncan mix and match the options in other ways, but you probably shouldn't \nunless you really know what you're doing.\"  Done.\n\n> Flexibility and orthogonality is often good, but uncontrolled flexibility\n> is not.\n\nThat seems to me to run directly counter to the design philosophy behind \ngit.\n\nrg\n"},{"id":"133093","messageId":"ron1-E17C62.22231529012010@news.gmane.org","threadId":"22441","inReplyTo":"76718491001292052x7f46d479lfeff7b66121502c3@mail.gmail.com","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-30T06:23:15Z","receivedAt":"2010-01-30T06:23:15Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article \n<76718491001292052x7f46d479lfeff7b66121502c3@mail.gmail.com>,\n Jay Soffian <jaysoffian@gmail.com> wrote:\n\n> On Fri, Jan 29, 2010 at 9:59 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> > Ron Garret <ron1@flownet.com> writes:\n> >\n> >> 1.  The term \"detached HEAD\" is inherently misleading.  A detached HEAD\n> >> isn't detached from anything, it's just pointing to the middle of a\n> >> branch, which is to say, to a commit that happens to already have\n> >> descendants.  For that matter, the name HEAD is itself misleading, since\n> >> HEAD need not be the head of a branch (though normally it is).  A better\n> >> name for HEAD would have been CURRENT or ACTIVE.  I recognize it's\n> >> probably too late to change it now.\n> >\n> > This description, especially the phrase \"middle of a branch\" shows that\n> > you don't understand git yet.  A git branch is _not_ a line (nor multiple\n> > lines) of development.  It is merely a _point_ in the history.\n> >\n> > \"A commit that is in the middle of an ancestry chain with existing\n> > descendants\" can be at the tip of a branch and does not have anything to\n> > do with detached HEAD state.\n> >\n> > When HEAD points at a branch, making a commit advances _that_ branch.  And\n> > we say you are \"on that branch\".  When HEAD is detached, because it is not\n> > attached to anything, it advances no branch.  \"detached HEAD\" is detached\n> > in the very real sense.  It is not attached to _any_ branch.\n> \n> Let me try wording this slightly different, because I think I can see\n> Ron's confusion.\n\n[snip]\n\n> So that was a really long explanation, but I hope it clears things up.\n\nYes, that was very helpful, thank you.\n\nMight it make more sense to talk about \"anonymous branches\" or \"unnamed \nbranches\" instead of \"detached heads\"?  I think something like the \nfollowing would be much easier to grasp:\n\nWARNING: Your HEAD is now pointing to a commit that is not a named\nbranch head.  As a result of this, any commits off of this one may\nbe lost during the next garbage collection.  If you want to prevent\nthis, you should give this branch head a name by doing ...\n\nrg\n"},{"id":"133094","messageId":"ron1-B18EFA.22250929012010@news.gmane.org","threadId":"22441","inReplyTo":"7v1vh8417w.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-30T06:25:09Z","receivedAt":"2010-01-30T06:25:09Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <7v1vh8417w.fsf@alter.siamese.dyndns.org>,\n Junio C Hamano <gitster@pobox.com> wrote:\n\n> Nicolas Pitre <nico@fluxnic.net> writes:\n> \n> > Could you please take this really nice explanation and make it into a \n> > patch adding a \"Detached HEAD\" section in the git-checkout.txt manual \n> > page please?\n> \n> Good suggestion.\n> \n> I'd be happier if the description didn't say \"SHA-1\", but instead said\n> \"object name\".\n> \n> Also it would be nicer (just a personal preference) if a picture that\n> forks only one branch forks it upwards, like this:\n> \n>              o---o\n>             /    \n>     ---o---o---o\n> \n> not downwards, like this:\n> \n>     ---o---o---o\n>             \\\n>              o---o\n\nJust out of curiosity, why does this matter to you?  Downwards seems \nmore intuitive to me.  Time should advance left to right and top to \nbottom IMHO.\n\nrg\n"},{"id":"133095","messageId":"7vaavw1478.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"ron1-FA4289.22165129012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T06:45:15Z","receivedAt":"2010-01-30T06:45:15Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ron Garret <ron1@flownet.com> writes:\n\n> No, because it would make it much easier to map intent back into a \n> command that implements that intent.  Don't forget, this whole thing \n> began because I wanted to do something very simple, tried what seemed to \n> be the obvious way to do it, and stumbled accidentally on an advanced \n> feature.  That would not have happened if I'd been able to just do a git \n> update --tree master^.\n\nDoing that _will_ confuse you in your next step.  Can you explain what\nhappens if you run \"git commit\" from that state, why \"git commit\" does so,\nand how that is useful?\n\nYou may be too narrowly focused on only one single step, but I am more\nworried about the whole user experience: \"I managed to do this, I am\nhappy, but then the next step doesn't make much sense.  Now what?\"\n\n> What difference does that make?  Sure, there would be ways to shoot \n> yourself in the foot with git update, but there is no shortage of ways \n> to shoot yourself in the foot now.\n\nAs long as you have a coherent picture of the workflow individual commands\nare supporting, there is no \"shoot yourself in the foot\".  \"git update\" on\nthe other hand is _designed_ not to allow such a coherent picture to be\nformed in the user's head, by letting random combinations that may or may\nnot make sense.\n\n> BTW, nothing prevents you from providing the usual repertoire of \n> higher-level functionality as thin layers on top of something like git \n> update.\n\nThat is more or less the same as what I said in the footnote, which you\ndidn't quote from my message.\n\nThe flexibility of \"update\" may help Porcelain writers to pick and use\nonly useful/usable combinations to present \"the usual repertoire\" for end\nusers.  At the philosophical level of \"building blocks\", I do not oppose\nto such flexibility [*1*].\n\nBut.\n\nAs the main point of Michael's message was that he thought it may make\nthings less confusing to the end users, I am pointing out that unleashing\nsuch an uncontrolled flexibility directly to end users will _not_ help\nreduce their confusion.\n\n[Footnote]\n\n*1* As a set of \"building blocks\" to implement \"reset\" and \"checkout\", I\ndon't necessarily agree that \"update\" would be a good way to go from the\nimplementation standpoint, but that is a totally separate matter.\n"},{"id":"133097","messageId":"ron1-0D3105.23314829012010@news.gmane.org","threadId":"22441","inReplyTo":"7vaavw1478.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-30T07:31:48Z","receivedAt":"2010-01-30T07:31:48Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <7vaavw1478.fsf@alter.siamese.dyndns.org>,\n Junio C Hamano <gitster@pobox.com> wrote:\n\n> Ron Garret <ron1@flownet.com> writes:\n> \n> > No, because it would make it much easier to map intent back into a \n> > command that implements that intent.  Don't forget, this whole thing \n> > began because I wanted to do something very simple, tried what seemed to \n> > be the obvious way to do it, and stumbled accidentally on an advanced \n> > feature.  That would not have happened if I'd been able to just do a git \n> > update --tree master^.\n> \n> Doing that _will_ confuse you in your next step.  Can you explain what\n> happens if you run \"git commit\" from that state,\n\nNothing.\n\n> why \"git commit\" does so,\n\nBecause my index would be empty.\n\n> and how that is useful?\n\nIt wouldn't.  Was this a trick question?  Did you mean to ask what would \nhappen if I ran commit -a?\n\n> You may be too narrowly focused on only one single step, but I am more\n> worried about the whole user experience: \"I managed to do this, I am\n> happy, but then the next step doesn't make much sense.  Now what?\"\n\nI think you may be making some unwarranted assumptions about my end goal.\n\n> > What difference does that make?  Sure, there would be ways to shoot \n> > yourself in the foot with git update, but there is no shortage of ways \n> > to shoot yourself in the foot now.\n> \n> As long as you have a coherent picture of the workflow individual commands\n> are supporting, there is no \"shoot yourself in the foot\".  \"git update\" on\n> the other hand is _designed_ not to allow such a coherent picture to be\n> formed in the user's head, by letting random combinations that may or may\n> not make sense.\n\nThat is a valid point.  I guess this depends on whether you think of git \nas merely a revision control system for computer source code, or if you \nthink of it as a more general tool that can and should be used in other \nkinds of applications as well.\n\n> > BTW, nothing prevents you from providing the usual repertoire of \n> > higher-level functionality as thin layers on top of something like git \n> > update.\n> \n> That is more or less the same as what I said in the footnote, which you\n> didn't quote from my message.\n\nYes, sorry about that.\n\n> The flexibility of \"update\" may help Porcelain writers to pick and use\n> only useful/usable combinations to present \"the usual repertoire\" for end\n> users.  At the philosophical level of \"building blocks\", I do not oppose\n> to such flexibility [*1*].\n> \n> But.\n> \n> As the main point of Michael's message was that he thought it may make\n> things less confusing to the end users, I am pointing out that unleashing\n> such an uncontrolled flexibility directly to end users will _not_ help\n> reduce their confusion.\n> \n> [Footnote]\n> \n> *1* As a set of \"building blocks\" to implement \"reset\" and \"checkout\", I\n> don't necessarily agree that \"update\" would be a good way to go from the\n> implementation standpoint, but that is a totally separate matter.\n\nDid you mean \"don't necessarily DISagree\"?\n\nrg\n"},{"id":"133101","messageId":"7vhbq4xbok.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"ron1-0D3105.23314829012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T08:02:35Z","receivedAt":"2010-01-30T08:02:35Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ron Garret <ron1@flownet.com> writes:\n\n> It wouldn't.  Was this a trick question?  Did you mean to ask what would \n> happen if I ran commit -a?\n\nI didn't mean _literally_ \"git commit\".  Any random thing you may want to\ndo when you come back to work the next day and find a checked out work\ntree.  Viewing, editing, committing, etc.\n\n>> *1* As a set of \"building blocks\" to implement \"reset\" and \"checkout\", I\n>> don't necessarily agree that \"update\" would be a good way to go from the\n>> implementation standpoint, but that is a totally separate matter.\n>\n> Did you mean \"don't necessarily DISagree\"?\n\nI have huge doubts that \"update\" is the best way to do reset/checkout.\n"},{"id":"133107","messageId":"ron1-817AFC.00562230012010@news.gmane.org","threadId":"22441","inReplyTo":"7vhbq4xbok.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-30T08:56:22Z","receivedAt":"2010-01-30T08:56:22Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <7vhbq4xbok.fsf@alter.siamese.dyndns.org>,\n Junio C Hamano <gitster@pobox.com> wrote:\n\n> Ron Garret <ron1@flownet.com> writes:\n> \n> > It wouldn't.  Was this a trick question?  Did you mean to ask what would \n> > happen if I ran commit -a?\n> \n> I didn't mean _literally_ \"git commit\".  Any random thing you may want to\n> do when you come back to work the next day and find a checked out work\n> tree.  Viewing, editing, committing, etc.\n\nThen I really don't understand the issue.  I'd be in a situation that is \nno different from (in fact indistinguishable from) having manually \nedited my code so that it looks like an earlier checked-in version.  \nWhat's the problem?\n\nrg\n"},{"id":"133108","messageId":"20100130085957.GA20112@coredump.intra.peff.net","threadId":"22441","inReplyTo":"alpine.LFD.2.00.1001291641200.1681@xanadu.home","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-01-30T08:59:57Z","receivedAt":"2010-01-30T08:59:57Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jan 29, 2010 at 04:51:18PM -0500, Nicolas Pitre wrote:\n\n> > Using a detached head is a more advanced feature than wanting to\n> > checkout a remote branch locally, creating a local tracking branch. As\n> > such, 'git checkout origin/topic' now means the same as 'git checkout\n> > -t origin/topic', and you can get the old behavior back by doing 'git\n> > checkout origin/topic^0'.\n> \n> What purpose does this \"feature\" serve?  Making sure people remain \n> stupid and get even more confused when the special dwimery doesn't work \n> because they don't know the difference between a local branch and a \n> remote tracking branch?\n> \n> And now people will be left wondering why after a fetch they don't get \n> the latest stuff when they do \"git checkout topic\" again.  Is this any \n> better?\n\nI am entering the discussion a bit late, and things have moved on from\nthis point, but I wanted to mention that I have in the past made the\nsame argument that you have in your second paragraph (that you leave\nusers _more_ confused after a fetch), but somebody (I think Jay) managed\nto convince me otherwise.\n\nThe saving feature is that we now print out the symmetric difference\ninformation between a branch and its upstream during checkout. So the\nuser experience looks like:\n\n  $ git checkout topic\n  Branch topic set up to track remote branch topic from origin.\n  Switched to a new branch 'topic'\n\n  ... time passes ...\n\n  $ git fetch\n  ...\n     9f137a4..22ac6a6  topic      -> origin/topic\n\n  $ git checkout topic\n  Switched to branch 'topic'\n  Your branch is behind 'origin/topic' by 6 commits, and can be fast-forwarded.\n\nSo I think it is not quite as bad as at least I had originally thought.\nThere are still a few rough edges, though:\n\n  1. If I stay on the 'topic' branch and run \"git fetch\", then I don't\n     see the checkout message. If I don't understand that a local branch\n     has been created, I might expect the new changes to be present. But\n     they're not. If I do a pull instead, it does \"just work\", even if I\n     am clueless about the local branch.\n\n     I wonder if a \"fetch\" which updates the upstream branch of the\n     current HEAD should print something like the \"Your branch is\n     behind...\" message.\n\n  2. If I am clueless that the local branch exists, I can see that there\n     are new changes that I can \"fast forward\". But if I am clueless\n     about local branches, do I know that means I need to run \"git merge\n     origin/topic\"?  However, I can't think of an improved message that\n     would make the situation clear without adding a bunch of annoying\n     text.\n\n-Peff\n"},{"id":"133129","messageId":"7vr5p7pi0r.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"ron1-B18EFA.22250929012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T18:25:08Z","receivedAt":"2010-01-30T18:25:08Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ron Garret <ron1@flownet.com> writes:\n\n>> Also it would be nicer (just a personal preference) if a picture that\n>> forks only one branch forks it upwards, like this:\n>> \n>>              o---o\n>>             /    \n>>     ---o---o---o\n>> \n>> not downwards, like this:\n>> \n>>     ---o---o---o\n>>             \\\n>>              o---o\n>\n> Just out of curiosity, why does this matter to you?\n\nImagine you pick up the whole assembly and let it fall (gravity works from\ntop to bottom of the sheet of paper it is printed on, not from above down\nto the face of paper it is printed on)?  Which one looks more stable and\nwould land on the floor as-is?\n\nThe top one, of course.  It sits better when printed, and especially so\nwhen it is presented as an illustration that comes before a paragraph,\nwhich is a more-or-less rectangular-looking block of text; at least it\nlooks that way to me.\n\nDidn't I say it is just a \"personal preference\"?  ;-)\n"},{"id":"133131","messageId":"ron1-25CA1F.10404030012010@news.gmane.org","threadId":"22441","inReplyTo":"20100130085957.GA20112@coredump.intra.peff.net","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-30T18:40:40Z","receivedAt":"2010-01-30T18:40:40Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <20100130085957.GA20112@coredump.intra.peff.net>,\n Jeff King <peff@peff.net> wrote:\n\n>      I can't think of an improved message that\n>      would make the situation clear without adding a bunch of annoying\n>      text.\n\nIn situations like that a pointer to the docs, or a keyword to search on \nis often sufficient.\n\nrg\n"},{"id":"133132","messageId":"7veil7pgb2.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"ron1-4F99DE.16184529012010@news.gmane.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-30T19:02:09Z","receivedAt":"2010-01-30T19:02:09Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ron Garret <ron1@flownet.com> writes:\n\n>> > > If I do a git reset --hard then I get the old version, but I lose my \n>> > > HEAD pointer so that git diff doesn't give me what I want any more.\n\nI think it would be helpful to point out one issue that may hurt you (and\nanybody who thinks \"git update --tree\" without --index is a good idea).\n\nKeeping the index and HEAD in sync but matching the work tree files to\nthat of a different commit has one major downside.  To git, a work tree\nfile that does not exist in the index is a yet-to-be-added-untracked file\n(that is how and why \"rm --cached file\" works, for example).  It won't\nparticipate in the diff output (other than being treated as \"no such file\nin the work tree version\").\n\nSuppose that you used to have a path in older revision, but not in the\ncurrent revision.  You remove everything from the work tree and replace it\nwith the files in the older revision, and you do not touch HEAD nor index.\n\"git diff -R\" appears to show \"what changed since that older version and\nthe latest\", because it compares what is in the index relative to what is\nin the work tree.  Nice.\n\nNot quite.  Since the index does not know that path you recently removed,\nyou won't see that path.  If you run \"git ls-files\" for a list of files\nknown to git, it wouldn't be shown either.\n\nYour original \"git checkout master^\" is a valid and probably the optimal\nway to get a checkout of a older revision (which you could feed to your\nrunning Lisp interpreter, in addition to being able to run \"less\" and\n\"make\" on them).  Exactly because the index is updated to that of the\nolder version, you won't lose the sight of the path that you removed in a\nlater version, and you can review the change with \"git diff -R master\".\n\nI think this is an XY problem that comes from your wanting to use \"git\ndiff\" (compare work tree with index) instead of \"git diff $commit\", and\nthat was because you wanted to use \"HEAD\" as a name of a commit.  If you\nused a branch name you originally came from, none of this desire to \"keep\nindex intact\" or \"keep HEAD intact\" would have been necessary.\n\nBut this is all tangent; I think you now know more about git to improve\nyour IDE integration, without fighting with git but instead taking\nadvantage of it.\n"},{"id":"133135","messageId":"ron1-EBAD29.11241330012010@news.gmane.org","threadId":"22441","inReplyTo":"7veil7pgb2.fsf@alter.siamese.dyndns.org","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Ron Garret","fromEmail":"ron1@flownet.com","sentAt":"2010-01-30T19:24:13Z","receivedAt":"2010-01-30T19:24:13Z","isPatch":false,"sender":{"key":"ron1@flownet.com","avatar":null},"body":"In article <7veil7pgb2.fsf@alter.siamese.dyndns.org>,\n Junio C Hamano <gitster@pobox.com> wrote:\n\n> Ron Garret <ron1@flownet.com> writes:\n> \n> >> > > If I do a git reset --hard then I get the old version, but I lose my \n> >> > > HEAD pointer so that git diff doesn't give me what I want any more.\n> \n> I think it would be helpful to point out one issue that may hurt you (and\n> anybody who thinks \"git update --tree\" without --index is a good idea).\n> \n> Keeping the index and HEAD in sync but matching the work tree files to\n> that of a different commit has one major downside.  To git, a work tree\n> file that does not exist in the index is a yet-to-be-added-untracked file\n> (that is how and why \"rm --cached file\" works, for example).  It won't\n> participate in the diff output (other than being treated as \"no such file\n> in the work tree version\").\n> \n> Suppose that you used to have a path in older revision, but not in the\n> current revision.  You remove everything from the work tree and replace it\n> with the files in the older revision, and you do not touch HEAD nor index.\n> \"git diff -R\" appears to show \"what changed since that older version and\n> the latest\", because it compares what is in the index relative to what is\n> in the work tree.  Nice.\n> \n> Not quite.  Since the index does not know that path you recently removed,\n> you won't see that path.  If you run \"git ls-files\" for a list of files\n> known to git, it wouldn't be shown either.\n> \n> Your original \"git checkout master^\" is a valid and probably the optimal\n> way to get a checkout of a older revision (which you could feed to your\n> running Lisp interpreter, in addition to being able to run \"less\" and\n> \"make\" on them).  Exactly because the index is updated to that of the\n> older version, you won't lose the sight of the path that you removed in a\n> later version, and you can review the change with \"git diff -R master\".\n> \n> I think this is an XY problem that comes from your wanting to use \"git\n> diff\" (compare work tree with index) instead of \"git diff $commit\", and\n> that was because you wanted to use \"HEAD\" as a name of a commit.  If you\n> used a branch name you originally came from, none of this desire to \"keep\n> index intact\" or \"keep HEAD intact\" would have been necessary.\n\nThat's a very good point.\n\n> But this is all tangent; I think you now know more about git to improve\n> your IDE integration, without fighting with git but instead taking\n> advantage of it.\n\nI hope so :-)\n\nThanks to everyone who responded in this thread.  It's been very \neducational.  I am very impressed at how supportive this community is to \na newcomer like me.\n\nrg\n"},{"id":"133169","messageId":"7vd40qg261.fsf@alter.siamese.dyndns.org","threadId":"22441","inReplyTo":"alpine.DEB.1.00.1001292131330.3749@intel-tinevez-2-302","subject":"Re: master^ is not a local branch -- huh?!?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-01-31T07:32:22Z","receivedAt":"2010-01-31T07:32:22Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Just as a general hint, I think the best documentation about Git was \n> written by J. Bruce Fields (the user manual) and Scott Chacon (everything \n> that has GitHub written on it, and Git Pro, and much, much more).\n\nThe last one is \"Pro Git\": http://progit.org/book/; highly recommended.\n\n> ... If you\n> happen to speak Japanese, Junio's book might help you understand the ideas \n> behind the current Git user interface, too.\n\nNah, I don't talk about UIs.  I talk more about concepts.\n"}]}