{"thread":{"id":"6618","subject":"Instructions concerning detached head lead to lost local changes","startedAt":"2007-02-01T22:51:04Z","lastAt":"2007-02-02T07:44:24Z","messageCount":9,"participants":["Carl Worth","Linus Torvalds","Junio C Hamano","Nicolas Pitre","Theodore Tso"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"33303","messageId":"87mz3xa3vr.wl%cworth@cworth.org","threadId":"6618","inReplyTo":null,"subject":"Instructions concerning detached head lead to lost local changes","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2007-02-01T22:51:04Z","receivedAt":"2007-02-01T22:51:04Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"So after some recent experiments to explore all this detached head\nstuff, I found myself making a change to my code having forgotten I\nhad some old state checked out.\n\nSo, I tried doing something like:\n\n\tgit checkout master\n\nin order to get where I wanted to be. I was stopped with the warning:\n\n\tYou are not on any branch and switching to branch 'master'\n\tmay lose your changes.  At this point, you can do one of two things:\n\t (1) Decide it is Ok and say 'git checkout -f master';\n\t (2) Start a new branch from the current commit, by saying\n\t     'git checkout -b <branch-name>'.\n\nAt this point, I _knew_ that I didn't care about the state I was\nleaving, (it was something random that I had done for testing). So I\ndefinitely didn't want to name it with option (2).\n\nI also knew I hadn't done any commits while detached, which is what I\nthought the warning was all about. So I wasn't worried about losing\nnothing with option (1).\n\nBut I found that after \"git checkout -f master\" I lost the dirty\nchanges I had made. And I don't see anything in the message above\ntelling me a better way to get from the state I was in to the state I\nwanted.\n\nI don't know if the \"-f\" always existed for git-checkout, or if it was\nadded to support this warning. But clearly, the current warning and\nsuggestion did not help in this case.\n\nAnd what would have worked great is if the original checkout had just\nworked and carried along my dirty changes, (just as would have\nhappened if I found I had accidentally made changes while on the wrong\nbranch instead of accidentally making changes while detached).\n\nCan we fix this please?\n\n-Carl\n"},{"id":"33318","messageId":"Pine.LNX.4.64.0702011536570.15057@woody.linux-foundation.org","threadId":"6618","inReplyTo":"87mz3xa3vr.wl%cworth@cworth.org","subject":"Re: Instructions concerning detached head lead to lost local changes","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-02-01T23:49:57Z","receivedAt":"2007-02-01T23:49:57Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 1 Feb 2007, Carl Worth wrote:\n> \n> But I found that after \"git checkout -f master\" I lost the dirty\n> changes I had made. And I don't see anything in the message above\n> telling me a better way to get from the state I was in to the state I\n> wanted.\n\nYeah, I think \"-f\" was a mistake. \n\nThere was already real meaning for \"-f\": force update of all the files, \nregardless of whether they are dirty or unmerged or anything else.\n\nAnd that meaning is totally independent of the new meaning of -f, which \nsays \"drop the old detached head\". Sometimes you might want to use them \ntogether, but they shouldn't really be tied together.\n\nMaybe something like this, which adds \"--drop\" as the flag to say \"ok to \ndrop the old detached head\"? I'm not married to that name, it's meant more \nas an RFC than as anything to be applied as-is.\n\nNOTE! This makes \"-f\" _imply_ \"--drop\" too, since it does make sense that \nif somebody just wants to force it, he can - regardless of any dirty \nstate, regardless of the current state of the HEAD.\n\nBut using just \"git checkout --drop new-head\" will have the old \"dirty \nstate follows along with branch changes\" semantics.\n\n\t\tLinus\n\nPS. I don't think \"--drop\" really makes much sense as a name. Especially \nwhen written out like that, it sounds like we're dropping the *new* \nbranch, not the old one. Maybe something like \"--no-check\" instead?\n\n---\ndiff --git a/git-checkout.sh b/git-checkout.sh\nindex deb4795..8e852df 100755\n--- a/git-checkout.sh\n+++ b/git-checkout.sh\n@@ -11,6 +11,7 @@ oldbranch=$(git-symbolic-ref $old_name 2>/dev/null)\n new=\n new_name=\n force=\n+drop=\n branch=\n newbranch=\n newbranch_log=\n@@ -36,10 +37,14 @@ while [ \"$#\" != \"0\" ]; do\n \t\t;;\n \t\"-f\")\n \t\tforce=1\n+\t\tdrop=1\n \t\t;;\n \t-m)\n \t\tmerge=1\n \t\t;;\n+\t--drop)\n+\t\tdrop=1\n+\t\t;;\n \t--)\n \t\tbreak\n \t\t;;\n@@ -163,7 +168,7 @@ If you want to create a new branch from this checkout, you may do so\n elif test -z \"$oldbranch\" && test -n \"$branch\"\n then\n \t# Coming back...\n-\tif test -z \"$force\"\n+\tif test -z \"$drop\"\n \tthen\n \t\tgit show-ref -d -s | grep \"$old\" >/dev/null || {\n \t\t\techo >&2 \\\n"},{"id":"33328","messageId":"7v1wl9mj48.fsf@assigned-by-dhcp.cox.net","threadId":"6618","inReplyTo":"87mz3xa3vr.wl%cworth@cworth.org","subject":"Re: Instructions concerning detached head lead to lost local changes","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-02T01:41:11Z","receivedAt":"2007-02-02T01:41:11Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Carl Worth <cworth@cworth.org> writes:\n\n> At this point, I _knew_ that I didn't care about the state I was\n> leaving, (it was something random that I had done for testing). So I\n> definitely didn't want to name it with option (2).\n>\n> I also knew I hadn't done any commits while detached, which is what I\n> thought the warning was all about. So I wasn't worried about losing\n> nothing with option (1).\n\nWell, the wording could probably be improved because you _did_\ncare about the state you were leaving (the \"state\" is not just\nwhat commit HEAD points at), but the suggestions did make it\nsound as if your had to choose between only these two, and\nneither would have worked for you.\n\n> Can we fix this please?\n\nThe question is how.\n\nWe can admit that suggestions are just suggestions and listing\nonly two is more confusing than not saying anything concrete.\n\nAlternatively we could add yet another suggestion that let's you\ndiscard the detached HEAD but still keep your local changes.\nEither --drop by Linus renamed to some sensible name, or \"the\nobscure but useful trick\".\n\nI dunno.\n"},{"id":"33330","messageId":"87bqkd9v38.wl%cworth@cworth.org","threadId":"6618","inReplyTo":"7v1wl9mj48.fsf@assigned-by-dhcp.cox.net","subject":"Re: Instructions concerning detached head lead to lost local changes","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2007-02-02T02:00:59Z","receivedAt":"2007-02-02T02:00:59Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Thu, 01 Feb 2007 17:41:11 -0800, Junio C Hamano wrote:\n> > Can we fix this please?\n>\n> The question is how.\n\nWhy not just allow the checkout when there's nothing to lose??\n\nIs there some technical reason this can't be done?\n\nIt's exactly what I wanted in this case and solves all problems about\nhow to word the message and what flags to require by not printing any\nmessage and not requiring any flags.\n\nWhat am I missing here? This seems quite obvious.\n\n-Carl\n"},{"id":"33331","messageId":"87abzx9uto.wl%cworth@cworth.org","threadId":"6618","inReplyTo":"7v1wl9mj48.fsf@assigned-by-dhcp.cox.net","subject":"Re: Instructions concerning detached head lead to lost local changes","fromName":"Carl Worth","fromEmail":"cworth@cworth.org","sentAt":"2007-02-02T02:06:43Z","receivedAt":"2007-02-02T02:06:43Z","isPatch":false,"sender":{"key":"cworth@cworth.org","avatar":"https://gravatar.com/avatar/3746dc28cde609bdbd7f939058356e7e2bbd16d21e32274df0725eb3d998bc5b?d=mp&s=160"},"body":"On Thu, 01 Feb 2007 17:41:11 -0800, Junio C Hamano wrote:\n> The question is how.\n\nI replied already about the no-warning-necessary case.\n\n> Alternatively we could add yet another suggestion that let's you\n> discard the detached HEAD but still keep your local changes.\n> Either --drop by Linus renamed to some sensible name, or \"the\n> obscure but useful trick\".\n\nBut, when the warning is necessary, then I would recommend changing\nthe -f suggestion to instead suggest --drop, (or whatever it ends up\ngetting named---I don't care much at all). I think it's fine (and\nsafer) to just remove the -f option altogether, rather than adding a\nthird option.\n\n-Carl\n"},{"id":"33333","messageId":"Pine.LNX.4.64.0702012135550.3021@xanadu.home","threadId":"6618","inReplyTo":"7v1wl9mj48.fsf@assigned-by-dhcp.cox.net","subject":"Re: Instructions concerning detached head lead to lost local changes","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2007-02-02T02:49:27Z","receivedAt":"2007-02-02T02:49:27Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Thu, 1 Feb 2007, Junio C Hamano wrote:\n\n> Alternatively we could add yet another suggestion that let's you\n> discard the detached HEAD but still keep your local changes.\n> Either --drop by Linus renamed to some sensible name, or \"the\n> obscure but useful trick\".\n> \n> I dunno.\n\nI have a feeling that proper reflog for HEAD would make the issue so \nmuch simpler.\n\nBut in the mean time I tend to agree with Ted about the fact that simply \nlosing the detached position is not _that_ important.  If you go to \nHEAD^ and want to come back to master I think it should just work (with \na display of what the last position was as Carl mentioned).\n\nIt might be some work to get to a given position with a detached head \nand this very position might be valuable information, but if you then do \n\"checkout HEAD^\" you will still be detached but your previous position \nis lost just like it would be if you moved to master.  Yet you're not \nprevented from going to HEAD^ but you are prevented from going to \nmaster.\n\nSame issue if you perform a commit on top of a detached head.  Nothing \nprevents you from doing \"checkout HEAD^\" which will leave your head \ndetached but it will also silently drop your last commit dangling.\n\nIn short I think there is no magic solution other than proper reflog for \nHEAD.\n\n\nNicolas\n"},{"id":"33348","messageId":"20070202065949.GI18880@thunk.org","threadId":"6618","inReplyTo":"Pine.LNX.4.64.0702012135550.3021@xanadu.home","subject":"Re: Instructions concerning detached head lead to lost local changes","fromName":"Theodore Tso","fromEmail":"tytso@mit.edu","sentAt":"2007-02-02T06:59:49Z","receivedAt":"2007-02-02T06:59:49Z","isPatch":false,"sender":{"key":"tytso@mit.edu","avatar":"https://avatars.githubusercontent.com/u/51416?v=4"},"body":"On Thu, Feb 01, 2007 at 09:49:27PM -0500, Nicolas Pitre wrote:\n> It might be some work to get to a given position with a detached head \n> and this very position might be valuable information, but if you then do \n> \"checkout HEAD^\" you will still be detached but your previous position \n> is lost just like it would be if you moved to master.  Yet you're not \n> prevented from going to HEAD^ but you are prevented from going to \n> master.\n\nExactly.  With Junio's reasoning, then why aren't we forcing -f in this sequence:\n\ngit checkout HEAD^\ngit checkout HEAD^^\ngit checkout HEAD^^^\ngit checkout -f master\n\nThe first three are just as likely to \"lose\" information as the last.\nPersonally, I don't think any of this is \"losing\" information, any\nmore than I \"lose\" information in the following sequence of commands:\n\ncd /usr/src/linux/drivers/net\ncd /usr/src/linux/drivers/char\ncd /usr/src/linux/fs/ext3\ncd /home/tytso\n\nThe current working directory is just like the detached HEAD.  If I'm\nmoving it around, there is no loss of data.  cd != rm.\n\n\t\t\t\t\t\t- Ted\n"},{"id":"33349","messageId":"Pine.LNX.4.64.0702020206480.3021@xanadu.home","threadId":"6618","inReplyTo":"20070202065949.GI18880@thunk.org","subject":"Re: Instructions concerning detached head lead to lost local changes","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2007-02-02T07:14:07Z","receivedAt":"2007-02-02T07:14:07Z","isPatch":false,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Fri, 2 Feb 2007, Theodore Tso wrote:\n\n> On Thu, Feb 01, 2007 at 09:49:27PM -0500, Nicolas Pitre wrote:\n> > It might be some work to get to a given position with a detached head \n> > and this very position might be valuable information, but if you then do \n> > \"checkout HEAD^\" you will still be detached but your previous position \n> > is lost just like it would be if you moved to master.  Yet you're not \n> > prevented from going to HEAD^ but you are prevented from going to \n> > master.\n> \n> Exactly.  With Junio's reasoning, then why aren't we forcing -f in this sequence:\n> \n> git checkout HEAD^\n> git checkout HEAD^^\n> git checkout HEAD^^^\n> git checkout -f master\n> \n> The first three are just as likely to \"lose\" information as the last.\n> Personally, I don't think any of this is \"losing\" information, any\n> more than I \"lose\" information in the following sequence of commands:\n> \n> cd /usr/src/linux/drivers/net\n> cd /usr/src/linux/drivers/char\n> cd /usr/src/linux/fs/ext3\n> cd /home/tytso\n> \n> The current working directory is just like the detached HEAD.  If I'm\n> moving it around, there is no loss of data.  cd != rm.\n\nIt's just that moving around amongst thousands of commits to pin point a \nparticular commit might require some digging work.  This is why there \nmight be some value in a particular position and why there is an attempt \nat protecting that \"work\".\n\nBut since moving to another position while still remaining detached from \nany branch has the same potential for losing the important position and \nso without any kind of protection then it makes no sense to have such a \nprotection when moving back to a branch.\n\n\nNicolas\n"},{"id":"33352","messageId":"7vps8thulj.fsf@assigned-by-dhcp.cox.net","threadId":"6618","inReplyTo":"Pine.LNX.4.64.0702020206480.3021@xanadu.home","subject":"Re: Instructions concerning detached head lead to lost local changes","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-02T07:44:24Z","receivedAt":"2007-02-02T07:44:24Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nicolas Pitre <nico@cam.org> writes:\n\n> It's just that moving around amongst thousands of commits to pin point a \n> particular commit might require some digging work.  This is why there \n> might be some value in a particular position and why there is an attempt \n> at protecting that \"work\".\n>\n> But since moving to another position while still remaining detached from \n> any branch has the same potential for losing the important position and \n> so without any kind of protection then it makes no sense to have such a \n> protection when moving back to a branch.\n\nThanks -- I'd agree.\n\nAlso I agree that \"reflog on HEAD\" is the right direction as it\nmakes these 'protection' unnecessary.  I've applied all your\npatches from today on the topic, along with Johannes's \"log -g\n@{now}\".\n"}]}