{"thread":{"id":"22474","subject":"Better cooperation between checkouts and stashing","startedAt":"2010-02-01T18:50:34Z","lastAt":"2010-04-10T22:31:38Z","messageCount":56,"participants":["Markus Elfring","Junio C Hamano","Eugene Sajine","Petr Baudis","Michael Witten","Avery Pennarun","Ramkumar Ramachandra"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"133280","messageId":"4B67227A.7030908@web.de","threadId":"22474","inReplyTo":null,"subject":"Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-02-01T18:50:34Z","receivedAt":"2010-02-01T18:50:34Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"Hello,\n\nThe content control tool \"Git\" maintains a single file system view that can be\nactively worked on. It can be switched to different topic branches by the\ncommand \"git checkout\". If the current active working copy contains \"dirty\"\nchanges, they need to be stashed away before each switch to a different issue.\nhttp://ariejan.net/2008/04/23/git-using-the-stash/\n\nI imagine that there are opportunities for further improvements.\n- How do you think about the feature that a checkout performs also a stash\noperation before by default and a stash would offer the option to checkout a\nbranch afterwards in one step?\n- Would you like to offer a more powerful filter expression for the command \"git\nstash list\" to make the navigation between the available intermediate work\nresults easier?\n\nRegards,\nMarkus\n"},{"id":"133284","messageId":"7vhbq0wuy6.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"4B67227A.7030908@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-01T20:40:49Z","receivedAt":"2010-02-01T20:40:49Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Markus Elfring <Markus.Elfring@web.de> writes:\n\n> The content control tool \"Git\" maintains a single file system view that can be\n> actively worked on. It can be switched to different topic branches by the\n> command \"git checkout\". If the current active working copy contains \"dirty\"\n> changes, they need to be stashed away before each switch to a different issue.\n> http://ariejan.net/2008/04/23/git-using-the-stash/\n>\n> I imagine that there are opportunities for further improvements.\n> - How do you think about the feature that a checkout performs also a stash\n> operation before by default and a stash would offer the option to checkout a\n> branch afterwards in one step?\n\nIf you are starting from \"if your work tree is dirty, you MUST stash\nbefore checking out another branch\", the suggestion is understandable.\nBut the thing is, that starting point is not quite correct.  And the end\nresult is that such a change you are suggesting would inconvenience people\ngreatly, I am afraid, if not designed carefully (I'll outline at the end).\n\nChecking out another branch (branch switching) is designed to carry your\nlocal modification across with you.  This is to allow you to start working\non something, realize that your changes are better suited for another\nbranch, and at that point after the fact \"git checkout\" that other branch,\nwhile keeping what you have done so far.\n\nIf the original branch you started your work from and the branch you are\nchecking out have different contents in files you have changed (aka \"your\nchanges conflict at the paths level\"), without -m option, \"git checkout\"\nrefuses to check out the other branch, because it will need a three-way\nmerge to carry your changes forward, and you might not be prepared to\nresolve conflicts resulting from such a merge.\n\nIn practice, however, your changes often don't conflict with the changes\nbetween the branches at the paths level, and \"git checkout\" lets you carry\nyour local changes across just fine.  I'd say this is the majority of the\ncase especially for experienced git users, as they tend to commit in\nsmaller and more logical units than those from other SCM background.\n\nForcing auto-stash on them would mean they now have to pop the stash,\nafter checking out the other branch, which is not an improvement for them\n(and remember, soon you will be part of \"them\" after getting used to git).\nDoing an auto-pop in addition to your auto-stash \"to help them\" is even\nworse, as you essentially made \"git checkout other-branch\" to always use\n\"-m\" option.\n\nI actually have explained this at least a few times here in the past:\n\n http://thread.gmane.org/gmane.comp.version-control.git/77700/focus=77708\n http://thread.gmane.org/gmane.comp.version-control.git/135661/focus=135663\n\nbut I don't see anything that states clearly that \"checkout\" is designed\nto carry your local changes across in any documentation (I gave a cursory\nlook to the user manual, tutorial and checkout manual page).  Probably\n\"git checkout --help\" needs a \"Switching branches\" section, just like the\nplanned enhancement for \"Detached HEAD\" section.\n\nWe _can_ start experimenting with an option (similar to \"checkout -m\"),\nwhich does:\n\n - Internally try 'git checkout other-branch' without disturbing the user\n   with any error message; if it does not fail due to paths level\n   conflicts, we have successfully checked out the other branch and we are\n   done;\n\n - If the above trial would fail for some other reason (perhaps your index\n   was unmerged), then don't do anything---just fail as before;\n\n - Internally run 'git stash', then run 'git checkout other-branch'.  If\n   either of these steps fail, you are in deep trouble.  Design what you\n   have to do carefully in this case (I won't do that in this message);\n\n - Then finally run 'git stash pop'.\n"},{"id":"133289","messageId":"4B674E36.40708@web.de","threadId":"22474","inReplyTo":"7vhbq0wuy6.fsf@alter.siamese.dyndns.org","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-02-01T21:57:10Z","receivedAt":"2010-02-01T21:57:10Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"\n> But the thing is, that starting point is not quite correct.\n\nThanks for your detailed explanations.\n\n\n\n> I actually have explained this at least a few times here in the past:\n>\n>  http://thread.gmane.org/gmane.comp.version-control.git/77700/focus=77708\n>   \n\nI am also very interested in the three use cases that were mentioned in\nthe discussion for the topic \"Switching branches without committing\nchanges\".\n\n\n> but I don't see anything that states clearly that \"checkout\" is designed\n> to carry your local changes across in any documentation (I gave a cursory\n> look to the user manual, tutorial and checkout manual page).\n\nI find it interesting that these descriptions might need still a few\nmore clarifications about the involved relationships.\n\n\n>  - Internally run 'git stash', then run 'git checkout other-branch'.\n>   \n\nI imagine that this case is useful because of usual work interruptions\nin software development. A developer tries to bring various tasks\nforward in parallel. Branches will be switched often with unfinished\nwork that needs to be kept before the reactivation of another task.\n\nRegards,\nMarkus\n"},{"id":"133291","messageId":"76c5b8581002011444t4f955fcdrd1f582f5c043f705@mail.gmail.com","threadId":"22474","inReplyTo":"4B674E36.40708@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Eugene Sajine","fromEmail":"euguess@gmail.com","sentAt":"2010-02-01T22:44:25Z","receivedAt":"2010-02-01T22:44:25Z","isPatch":false,"sender":{"key":"euguess@gmail.com","avatar":null},"body":">\n> I imagine that this case is useful because of usual work interruptions\n>\n> in software development. A developer tries to bring various tasks\n>\n> forward in parallel. Branches will be switched often with unfinished\n>\n> work that needs to be kept before the reactivation of another task.\n>\n\nAren't this and similar statements based on a general problem of\npeople being afraid to commit, because CVS/SVN taught them to be\naffraid? We are in progress of migrating from CVS to GIT and this is\none of the things i'm desperately fighting with.\nIn Git Commit doesn't equal Share (it does in CVS), so why not to\ncommit and save your work in progress and switch branches painlessly?\n\nThanks,\nEugene\n"},{"id":"133310","messageId":"20100202013647.GM9553@machine.or.cz","threadId":"22474","inReplyTo":"76c5b8581002011444t4f955fcdrd1f582f5c043f705@mail.gmail.com","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2010-02-02T01:36:47Z","receivedAt":"2010-02-02T01:36:47Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Mon, Feb 01, 2010 at 05:44:25PM -0500, Eugene Sajine wrote:\n> >\n> > I imagine that this case is useful because of usual work interruptions\n> >\n> > in software development. A developer tries to bring various tasks\n> >\n> > forward in parallel. Branches will be switched often with unfinished\n> >\n> > work that needs to be kept before the reactivation of another task.\n> >\n> \n> Aren't this and similar statements based on a general problem of\n> people being afraid to commit, because CVS/SVN taught them to be\n> affraid? We are in progress of migrating from CVS to GIT and this is\n> one of the things i'm desperately fighting with.\n> In Git Commit doesn't equal Share (it does in CVS), so why not to\n> commit and save your work in progress and switch branches painlessly?\n\nThere are various pressures pushing against each other and the balance\nwill be different for each individual and each project. One aspect is\nthat committing often is encouraged. However, greatly contradicting\nforce is the pressure to have \"clean history\" - that is, self-contained,\nclearly separated cnd bisectable ommits which introduce independent\nchanges and are pretty to look at, frequently quite different to\nchronological log of the performed work.\n\nOf course you can ignore that and just commit away, or build up large\nchanges \"in advance\", then split them up at once. The resulting number\nof commits will be about the same, but their quality _and_ the spent\neffort will be quite different. Optimum lies in appropriate balance of\nthe processes, as usual.\n\nThere are several ways to achieve the latter process, moreover. One\npossibility is to do all changes in the working tree, then carefulling\nfactoring out various aspects to separate commits using index\nmanipulation and heavy `git add -p` usage; you would then certainly need\n`git stash` in case you wanted to switch the branch. The other way is\nto commit regularly creating a history structure similar to the\n\"careless committer\", _however_ before pushing out and publishing the\ncommits, the history gets cleaned up and rewritten by `git rebase -i`.\n\nChoosing the appropriate method involves all kinds of subtle tradeoffs\nand I wonder whether there is a single good answer, it is a matter of\ntaste. I do the former, but maybe that's because I just dislike rebase\nfor different reasons. ;-) One natural way would be to hack in the\nworking tree, splitting up your work to 1-3 commits in the index, then\nreviewing your complete local changeset and tweaking it by rebase -i\nbefore finally publishing your self-contained masterpiece.\n\nFor better or worse, There Is More Than One Way To Do It in Git. ;-)\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nIf you can't see the value in jet powered ants you should turn in\nyour nerd card. -- Dunbal (464142)\n"},{"id":"133344","messageId":"4B67FDEC.80005@web.de","threadId":"22474","inReplyTo":"20100202013647.GM9553@machine.or.cz","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-02-02T10:26:52Z","receivedAt":"2010-02-02T10:26:52Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"\n> For better or worse, There Is More Than One Way To Do It in Git. ;-)\n>   \n\nDo you see also a need for improvements in the cooperation between the\nfunctions \"checkout\" and \"stash\"?\nWould it be useful to combine them into a single command on demand to\nmake the switching of branches without committing\nchanges a bit more convenient?\n\nRegards,\nMarkus\n"},{"id":"133347","messageId":"20100202110416.GN9553@machine.or.cz","threadId":"22474","inReplyTo":"4B67FDEC.80005@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2010-02-02T11:04:16Z","receivedAt":"2010-02-02T11:04:16Z","isPatch":false,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Tue, Feb 02, 2010 at 11:26:52AM +0100, Markus Elfring wrote:\n> \n> > For better or worse, There Is More Than One Way To Do It in Git. ;-)\n> >   \n> \n> Do you see also a need for improvements in the cooperation between the\n> functions \"checkout\" and \"stash\"?\n> Would it be useful to combine them into a single command on demand to\n> make the switching of branches without committing\n> changes a bit more convenient?\n\nI personally prefer to tell Git explicitly what to do when I'm\ncheckouting a different branch, and have a habit of checking what kind\nof uncommitted changes I have all the time (and I think it's a good\nhabit ;-), so I have no problem with explicitly stashing before\ncheckouting different branch if I need to.\n\nThe thing is, I use multiple branches less than I should. If I used them\nmore, I'd probably be simply using stash much less than making temporary\ncommits and possibly cleaning them up later instead. (But if you get\nreally used to sensibly separating commits, you end up actually adjusting\nyour programming process subconsciously in a way to lend to the\nappropriate commit sequence naturally.)\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nIf you can't see the value in jet powered ants you should turn in\nyour nerd card. -- Dunbal (464142)\n"},{"id":"134067","messageId":"4B71B574.3010609@web.de","threadId":"22474","inReplyTo":"7vhbq0wuy6.fsf@alter.siamese.dyndns.org","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-02-09T19:20:20Z","receivedAt":"2010-02-09T19:20:20Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"\n>\n> We _can_ start experimenting with an option (similar to \"checkout -m\"),\n> which does:\n>   \n\nDoes the documentation need any improvements on the dependencies between\nthe mentioned subfunctions?\nWould we like to collect further ideas on the suggested issue?\n\nRegards,\nMarkus\n"},{"id":"134072","messageId":"7vbpfy9nt4.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"4B71B574.3010609@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-09T20:06:15Z","receivedAt":"2010-02-09T20:06:15Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Markus Elfring <Markus.Elfring@web.de> writes:\n\n>>\n>> We _can_ start experimenting with an option (similar to \"checkout -m\"),\n>> which does:\n>>   \n>\n> Does the documentation need any improvements on the dependencies between\n> the mentioned subfunctions?\n\nSorry, you lost me.  I did say and still think that it would be good to\nhave in the documentation a separate section that teaches the users what\nhappens to their uncommitted changes when checking out a different branch\n(or an unnamed branch).  But I am at loss guessing what dependencies among\nwhat \"subfunctions\" you are talking about.\n"},{"id":"134075","messageId":"4B71CD2F.9040206@web.de","threadId":"22474","inReplyTo":"7vbpfy9nt4.fsf@alter.siamese.dyndns.org","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-02-09T21:01:35Z","receivedAt":"2010-02-09T21:01:35Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"\n>\n> But I am at loss guessing what dependencies among what \"subfunctions\"\n> you are talking about.\n>   \n\nI propose further clarifications and improvements between the git\nfunctions \"checkout\" and \"stash\".\n\nRegards,\nMarkus\n"},{"id":"134980","messageId":"4B7D7C5E.7060807@web.de","threadId":"22474","inReplyTo":"7vbpfy9nt4.fsf@alter.siamese.dyndns.org","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-02-18T17:43:58Z","receivedAt":"2010-02-18T17:43:58Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"\n> I did say and still think that it would be good to have in the documentation \n> a separate section that teaches the users what happens to their uncommitted \n> changes when checking out a different branch (or an unnamed branch).\n>   \n\nHow are the chances to achieve progress on this issue?\n\nRegards,\nMarkus\n"},{"id":"134997","messageId":"7vaav6b925.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"4B7D7C5E.7060807@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-18T20:09:06Z","receivedAt":"2010-02-18T20:09:06Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Markus Elfring <Markus.Elfring@web.de> writes:\n\n>> I did say and still think that it would be good to have in the documentation \n>> a separate section that teaches the users what happens to their uncommitted \n>> changes when checking out a different branch (or an unnamed branch).\n>\n> How are the chances to achieve progress on this issue?\n\nHow would _I_ know?  It depends on the probability of somebody who cares\nabout improving the documentation having enough time and motivation to do\nthe actual work, and submitting the patch.  It also depends on the quality\nof the result.\n"},{"id":"135855","messageId":"4B898F97.90706@web.de","threadId":"22474","inReplyTo":"7vhbq0wuy6.fsf@alter.siamese.dyndns.org","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-02-27T21:33:11Z","receivedAt":"2010-02-27T21:33:11Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> If you are starting from \"if your work tree is dirty, you MUST stash\n> before checking out another branch\", the suggestion is understandable.\n> But the thing is, that starting point is not quite correct.\n\nDoes an option exist for the command \"git checkout\" to return to the specified\nbranch without modifications in one step?\nWhen will it not be needed to reset the work tree to the last corresponding commit?\n\nRegards,\nMarkus\n"},{"id":"135857","messageId":"7vr5o6s5xf.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"4B898F97.90706@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-02-27T21:51:56Z","receivedAt":"2010-02-27T21:51:56Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Markus Elfring <Markus.Elfring@web.de> writes:\n\n>> If you are starting from \"if your work tree is dirty, you MUST stash\n>> before checking out another branch\", the suggestion is understandable.\n>> But the thing is, that starting point is not quite correct.\n> ...\n> When will it not be needed to reset the work tree to the last corresponding commit?\n\nA response to a month old message is a blast from the past ;-).\n\nThe answer is \"almost always\" for me.  IOW, if checkout stashed away my\nlocal changes, it would be very inconvenient.\n\nIt is important to understand that a local change does not belong to your\ncurrent branch (it does not belong to _any_ branch).  It belongs to you,\nand you can take it around while switching between branches.  And that is\na big time-saving feature.\n\nThis lets you work like this:\n\n - You are reading a mailing list message that asks for help, and you know\n   the solution---you can give the help real quick.\n\n - You hack in whatever branch that happen to be checked out.  The change\n   is perfect, it works.\n\n - The branch you happen to have checked out was 'next', but the solution\n   is a bugfix, and should go to 'maint'.\n\nNow, at this point, you want to checkout 'maint' without losing your local\nchange.  The paths you touched with your quick fix are often not different\nbetween the two branches, and \"checkout maint\" will checkout the branch\nwhile keeping your local changes intact.  All that is left for you to do\nis to run another round of test to make sure that your fix didn't depend\non anything not in 'maint' and commit the change with appropriate log\nmessage, and then you can go back to whatever you were doing with\n\"checkout next\".\n\nWhen the change involves paths that were touched between 'maint' and\n'next', of course you won't be able to switch without merging the local\nchange to the difference between 'next' and 'maint'.  There are a few\nworkflows to deal with such a case, and the easiest is \"checkout -m\", if\nyou are confident that you can resolve it.\n\nIn a case where \"checkout -m\" would result in a conflict too big to\nresolve, the original fix you made would not be applicable to 'maint'\n(iow, you should have solved it differently starting from 'maint'), and\nyou may end up doing \"reset --hard\" and start from scratch, but that is a\nrare worst case.\n\nI said it is rare, because you would notice, while doing the \"quick fix\"\nbased on 'next' codebase, that the code you are touching have changed\nsince 'maint' and won't be applicable to its final destination (by that\ntime you know you are \"fixing\"), and you won't waste too much time\ncontinuing to work in a checkout of 'next'.\n"},{"id":"135877","messageId":"4B8A75D9.2090702@web.de","threadId":"22474","inReplyTo":"7vr5o6s5xf.fsf@alter.siamese.dyndns.org","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-02-28T13:55:37Z","receivedAt":"2010-02-28T13:55:37Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> It is important to understand that a local change does not belong to your\n> current branch (it does not belong to _any_ branch).  It belongs to you,\n> and you can take it around while switching between branches.  And that is\n> a big time-saving feature.\n\nIt seems that we have got different expectations on the editing work flow when\nwe discuss the following situation.\n\nelfring@Sonne:~/Projekte> git --version && mkdir try && cd try && git init --quiet \\\n> && echo one > XYZ.h && git add . && git commit --message=check-in --quiet \\\n> && git checkout --quiet -b feature1 && echo two > XYZ.h \\\n> && git checkout --quiet master && git status\ngit version 1.7.0\n# On branch master\n# Changed but not updated:\n#   (use \"git add <file>...\" to update what will be committed)\n#   (use \"git checkout -- <file>...\" to discard changes in working directory)\n#\n#       modified:   XYZ.h\n#\nno changes added to commit (use \"git add\" and/or \"git commit -a\")\n\nI would prefer to return to the unchanged work tree because I made an adjustment\nfor a source file with the intention that this update should only belong to the\nnew topic branch. The switch did not provide a clean state from my view.\n\n\n>  - You are reading a mailing list message that asks for help, and you know\n>    the solution---you can give the help real quick.\n> \n>  - You hack in whatever branch that happen to be checked out.\n\nI would create another topic branch before.\n\n\n>  - The branch you happen to have checked out was 'next', but the solution\n>    is a bugfix, and should go to 'maint'.\n> \n> Now, at this point, you want to checkout 'maint' without losing your local\n> change.  The paths you touched with your quick fix are often not different\n> between the two branches, and \"checkout maint\" will checkout the branch\n> while keeping your local changes intact.\n\nI can follow your view on convenience if the desired software maintenance is so\neasy as in this example. I guess that it matters if only a simple branch switch\nis needed or a corresponding content restore will also be required.\n\n\n> In a case where \"checkout -m\" would result in a conflict too big to\n> resolve, the original fix you made would not be applicable to 'maint'\n> (iow, you should have solved it differently starting from 'maint'), and\n> you may end up doing \"reset --hard\" and start from scratch, but that is a\n> rare worst case.\n\nI would like to be more careful so that I do not want to mix changes by accident.\n\n\n> I said it is rare, because you would notice, while doing the \"quick fix\"\n> based on 'next' codebase, that the code you are touching have changed\n> since 'maint' and won't be applicable to its final destination (by that\n> time you know you are \"fixing\"), and you won't waste too much time\n> continuing to work in a checkout of 'next'.\n\nI imagine that stashing will help to split the collected changes for different\nbranch targets.\n\nRegards,\nMarkus\n"},{"id":"135917","messageId":"b4087cc51002281457id4e4de6l98ade122312602a2@mail.gmail.com","threadId":"22474","inReplyTo":"4B8A75D9.2090702@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2010-02-28T22:57:25Z","receivedAt":"2010-02-28T22:57:25Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"On Sun, Feb 28, 2010 at 07:55, Markus Elfring <Markus.Elfring@web.de> wrote:\n>\n> I would prefer to return to the unchanged work tree because I made an adjustment\n> for a source file with the intention that this update should only belong to the\n> new topic branch. The switch did not provide a clean state from my view.\n\nI don't think you're properly reading what Junio has been saying. I\nsuggest you look\nover this thread again from the beginning.\n"},{"id":"135937","messageId":"4B8B9BF1.10408@web.de","threadId":"22474","inReplyTo":"7vr5o6s5xf.fsf@alter.siamese.dyndns.org","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-01T10:50:25Z","receivedAt":"2010-03-01T10:50:25Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":">  - The branch you happen to have checked out was 'next', but the solution\n>    is a bugfix, and should go to 'maint'.\n> \n> Now, at this point, you want to checkout 'maint' without losing your local\n> change.  The paths you touched with your quick fix are often not different\n> between the two branches, and \"checkout maint\" will checkout the branch\n> while keeping your local changes intact.\n\nDoes the wording in the manual fit to the mentioned software development practice?\n\n\"When <paths> are not given, this command switches branches by updating the\nindex, working tree, and HEAD to reflect the specified branch.\"\n\nI see a need for further clarifications of the involved details.\n- Only the focus will be set on the specified branch.\n- Would it be useful if it will become configurable if the corresponding\ncontents will also be automatically restored by a checkout?\n\nRegards,\nMarkus\n"},{"id":"135955","messageId":"4b8bf32f.0706c00a.26cb.691d@mx.google.com","threadId":"22474","inReplyTo":"4B8B9BF1.10408@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2010-03-01T17:02:39Z","receivedAt":"2010-03-01T17:02:39Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"\nTo Junio in particular: See the very bottom of this email.\n\n\nOn Mon, Mar 1, 2010 at 04:50, Markus Elfring <Markus.Elfring@web.de> wrote:\n>>  - The branch you happen to have checked out was 'next', but the solution\n>>    is a bugfix, and should go to 'maint'.\n>>\n>> Now, at this point, you want to checkout 'maint' without losing your local\n>> change.  The paths you touched with your quick fix are often not different\n>> between the two branches, and \"checkout maint\" will checkout the branch\n>> while keeping your local changes intact.\n>\n> Does the wording in the manual fit to the mentioned software development practice?\n>\n> \"When <paths> are not given, this command switches branches by updating the\n> index, working tree, and HEAD to reflect the specified branch.\"\n>\n> I see a need for further clarifications of the involved details.\n\nJunio pointed out that the documentation is currently lacking:\n\n  [Unfortunately,] I don't see anything that states\n  clearly that \"checkout\" is designed to carry your\n  local changes across in any documentation (I gave\n  a cursory look to the user manual, tutorial and\n  checkout manual page). Probably \"git checkout --help\"\n  needs a \"Switching branches\" section, just like the\n  planned enhancement for \"Detached HEAD\" section.\n\nIn other words, the documentation NEEDS to be updated to include\nthe explanation and rationale that Junio also supplied:\n\n  Checking out another branch (branch switching) is\n  designed to carry your local modification across\n  with you. This is to allow you to start working on\n  something, realize that your changes are better suited\n  for another branch, and at that point after the fact\n  \"git checkout\" that other branch, while keeping what\n  you have done so far.\n\n  If the original branch you started your work from and\n  the branch you are checking out have different contents\n  in files you have changed (aka \"your changes conflict\n  at the paths level\"), without -m option, \"git checkout\"\n  refuses to check out the other branch, because it will\n  need a three-way merge to carry your changes forward,\n  and you might not be prepared to resolve conflicts\n  resulting from such a merge.\n\n  In practice, however, your changes often don't conflict\n  with the changes between the branches at the paths\n  level, and \"git checkout\" lets you carry your local\n  changes across just fine. I'd say this is the majority\n  of the case especially for experienced git users, as\n  they tend to commit in smaller and more logical units\n  than those from other SCM background.\n\nand Junio expanded on this later:\n\n  It is important to understand that a local change does\n  not belong to your current branch (it does not belong to\n  _any_ branch). It belongs to you, and you can take it\n  around while switching between branches. And that is a\n  big time-saving feature.\n  \n  This lets you work like this:\n  \n   - You are reading a mailing list message that\n   asks for help, and you know the solution---you\n   can give the help real quick.\n  \n   - You hack in whatever branch that happen to be\n   checked out. The change is perfect, it works.\n  \n   - The branch you happen to have checked out\n   was 'next', but the solution is a bugfix, and\n   should go to 'maint'.\n  \n  Now, at this point, you want to checkout 'maint' without\n  losing your local change. The paths you touched with\n  your quick fix are often not different between the two\n  branches, and \"checkout maint\" will checkout the branch\n  while keeping your local changes intact. All that is\n  left for you to do is to run another round of test to\n  make sure that your fix didn't depend on anything not\n  in 'maint' and commit the change with appropriate log\n  message, and then you can go back to whatever you were\n  doing with \"checkout next\".\n  \n  When the change involves paths that were touched\n  between 'maint' and 'next', of course you won't be\n  able to switch without merging the local change to the\n  difference between 'next' and 'maint'. There are a few\n  workflows to deal with such a case, and the easiest is\n  \"checkout -m\", if you are confident that you can resolve\n  it.\n\n  In a case where \"checkout -m\" would result in a conflict\n  too big to resolve, the original fix you made would not\n  be applicable to 'maint' (iow, you should have solved it\n  differently starting from 'maint'), and you may end up\n  doing \"reset --hard\" and start from scratch, but that is\n  a rare worst case.\n\n  I said it is rare, because you would notice, while doing\n  the \"quick fix\" based on 'next' codebase, that the code\n  you are touching have changed since 'maint' and won't be\n  applicable to its final destination (by that time you\n  know you are \"fixing\"), and you won't waste too much\n  time continuing to work in a checkout of 'next'.\n\nI think it would be a great contribution if you could clean up\nJunio's explanation and submit a patch that includes it in the\ndocumentation for \"git checkout\".\n\n> - Would it be useful if it will become configurable if the corresponding\n> contents will also be automatically restored by a checkout?\n\n>From what you've said, I think you essentially want to implement\n\"git checkout\" with something like the following (this hack is **not**\nmeant as a solution; it is only meant to illustrate what I think is\nMarkus Elfring's desire):\n\n  # Utility:\n\n    get_stash_id()\n    {\n      local branch=$(git rev-parse --symbolic-full-name HEAD)\n      [ $branch = HEAD ] && return 1 # don't stash for detached HEAD\n      echo -n \"$branch\" | md5sum | awk -F\" \" '{print $1}'\n    }\n\n  # New implementation:\n\n    checkout()\n    {\n      # Stash local modifications (including index modifications) if\n      # necessary, using an easily identifiable message known as the\n      # 'stash id':\n\n\tlocal stash_id\n        stash_id=$(get_stash_id) &&\n          git stash save -q \"$stash_id\" ||    # Save local modifications\n            git reset --hard HEAD             # Throw away changes on detached HEAD\n\n      # Do the checkout that was requested:\n\n        git checkout \"$@\"\n\n      # Unstash previously stashed local modifications (including\n      # index modifications) if they were automatically stashed\n      # before (the lookup is done with the relevant 'stash id'):\n\n        stash_id=$(get_stash_id)                                            &&\n          stash_id=$(git stash list | awk -F': ' \"/$stash_id/ {print \\$1}\") &&\n            [ -n \"$stash_id\" ]                                              &&\n              git stash pop --index \"$stash_id\"\n    }\n\nSincerely,\nMichael Witten\n"},{"id":"135959","messageId":"7v1vg4ufas.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"4b8bf32f.0706c00a.26cb.691d@mx.google.com","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-01T17:23:23Z","receivedAt":"2010-03-01T17:23:23Z","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> ..., I think you essentially want to implement\n> \"git checkout\" with something like the following (this hack is **not**\n> meant as a solution; it is only meant to illustrate what I think is\n> Markus Elfring's desire):\n\nYour \"checkout\" needs a bit better error checking.  For example, you don't\nwant to \"reset --hard\" when stash failed for whatever reason.\n\nFor performance and cleanliness reasons, it should first try a branch\nswitch, and only after seeing it fail due to local changes, perform your\nstash-unstash magic.  You would probably want to use the usual \"stash\nsave\", as you will be consuming the stashed change yourself as its first\nuser, and \"pop\" will clear it if things resolve cleanly, or the stash will\nbe left as the first element to make it easy to re-attempt the conflict\nresolution.  No need for stash-id nor special casing of detached HEAD\nsituation.\n\nAnd it should do all that only under \"-m\" option, i.e. when the user\nindicated that s/he is willilng to face conflict resolution while\nswitching.  That would be a genuine improvement compared to the current\nsystem (and I suspect it would be easier to implement).  \"checkout -m\" so\nfar has been as bad as \"CVS/SVN update\" in that it can get you into an\nunresolvable mess without a chance to go back and retry.  autostash will\nremedy that.\n"},{"id":"135962","messageId":"4b8c0420.5544f10a.2eb2.ffffb4c4@mx.google.com","threadId":"22474","inReplyTo":"7v1vg4ufas.fsf@alter.siamese.dyndns.org","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2010-03-01T18:14:56Z","receivedAt":"2010-03-01T18:14:56Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"On Mon, Mar 1, 2010 at 11:23, Junio C Hamano <gitster@pobox.com> wrote:\n> Your \"checkout\" needs a bit better error checking.  For example, you\n> don't want to \"reset --hard\" when stash failed for whatever reason.\n\nYes, you are correct.\n\nHowever, in my defense, the goal was just to illustrate the gist\nof the desired functionality.\n\n> For performance and cleanliness reasons, it should first try a branch\n> switch, and only after seeing it fail due to local changes, perform your\n> stash-unstash magic.  You would probably want to use the usual \"stash\n> save\", as you will be consuming the stashed change yourself as its first\n> user, and \"pop\" will clear it if things resolve cleanly, or the stash will\n> be left as the first element to make it easy to re-attempt the conflict\n> resolution.  No need for stash-id nor special casing of detached HEAD\n> situation.\n>\n> And it should do all that only under \"-m\" option, i.e. when the user\n> indicated that s/he is willilng to face conflict resolution while\n> switching.  That would be a genuine improvement compared to the current\n> system (and I suspect it would be easier to implement).  \"checkout -m\" so\n> far has been as bad as \"CVS/SVN update\" in that it can get you into an\n> unresolvable mess without a chance to go back and retry.  autostash will\n> remedy that.\n\nYou've still got the wrong problem in your head (though you're\nsolving a more useful issue).\n\nMarkus Elfring's goal (I think) is to associate local modifications with\na particular branch, *not* carry them across branches; that is, the goal\nis to stash local modifications away when we leave a branch and only pop\nthem off the stash when we RETURN to that same branch.\n\nHere's an example using the previously defined custom `checkout' function\n(don't bother trying to follow the file modifications exactly; what's\nimportant is how the stash is used during `checkout'):\n\n  $ git init repo\n  Initialized empty Git repository in /home/michael/repo/.git/\n\n\n  $ cd repo\n  $ echo 0 > file_0\n  $ git add file_0\n  $ git commit -m 0\n  [master (root-commit) 26ea762] 0\n   1 files changed, 1 insertions(+), 0 deletions(-)\n   create mode 100644 file_0\n\n\n  $ echo 1 > file_1\n  $ git add file_1\n  $ git commit -m 1\n  [master 2faaa55] 1\n   1 files changed, 1 insertions(+), 0 deletions(-)\n   create mode 100644 file_1\n\n\n  $ echo 2 > file_0\n  $ echo 3 > file_1\n  $ git add file_1\n\n\n  $ git branch branch\n  $ checkout branch               # Note: That's the custom 'checkout'\n  Switched to branch 'branch'\n\n\n  $ git stash list | cat\n  stash@{0}: On master: e2f0bfbd9de98acd4941a1842e4bc55f\n\n\n  $ echo 4 > file_0\n  $ checkout HEAD^\n  Note: checking out '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 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 26ea762... 0\n\n\n  $ git stash list | cat\n  stash@{0}: On branch: 3e4d8fe5cbdcf73b9272ad21b4510424\n  stash@{1}: On master: e2f0bfbd9de98acd4941a1842e4bc55f\n\n\n  $ echo 5 > file_0 \n\n\n  $ checkout master\n  HEAD is now at 26ea762 0\n  Previous HEAD position was 26ea762... 0\n  Switched to branch 'master'\n  # On branch master\n  # Changes to be committed:\n  #   (use \"git reset HEAD <file>...\" to unstage)\n  #\n  #\tmodified:   file_1\n  #\n  # Changed but not updated:\n  #   (use \"git add <file>...\" to update what will be committed)\n  #   (use \"git checkout -- <file>...\" to discard changes in working directory)\n  #\n  #\tmodified:   file_0\n  #\n  Dropped stash@{1} (6871afd660a5814a1caffe5275a9c145dba3c85a)\n\n\n  $ git stash list | cat\n  stash@{0}: On branch: 3e4d8fe5cbdcf73b9272ad21b4510424\n\n\n  $ checkout branch\n  Switched to branch 'branch'\n  # On branch branch\n  # Changed but not updated:\n  #   (use \"git add <file>...\" to update what will be committed)\n  #   (use \"git checkout -- <file>...\" to discard changes in working directory)\n  #\n  #\tmodified:   file_0\n  #\n  no changes added to commit (use \"git add\" and/or \"git commit -a\")\n  Dropped stash@{1} (f6ecf1ceed97c760cb2b3279bbb39fc1cd16f052)\n\n\n  $ git stash list | cat\n  stash@{0}: On master: e2f0bfbd9de98acd4941a1842e4bc55f\n\n\n  $ checkout master\n  Switched to branch 'master'\n  # On branch master\n  # Changes to be committed:\n  #   (use \"git reset HEAD <file>...\" to unstage)\n  #\n  #\tmodified:   file_1\n  #\n  # Changed but not updated:\n  #   (use \"git add <file>...\" to update what will be committed)\n  #   (use \"git checkout -- <file>...\" to discard changes in working directory)\n  #\n  #\tmodified:   file_0\n  #\n  Dropped stash@{1} (46a64d63441a924d9684c8a733a9fae4c7aa4b92)\n\n\n  $ git stash list | cat\n  stash@{0}: On branch: 3e4d8fe5cbdcf73b9272ad21b4510424\n\n  $ git diff | cat\n  diff --git a/file_0 b/file_0\n  index 573541a..0cfbf08 100644\n  --- a/file_0\n  +++ b/file_0\n  @@ -1 +1 @@\n  -0\n  +2\n\n  $ git diff --staged | cat\n  diff --git a/file_1 b/file_1\n  index d00491f..00750ed 100644\n  --- a/file_1\n  +++ b/file_1\n  @@ -1 +1 @@\n  -1\n  +3\n\netc.\n"},{"id":"135965","messageId":"4B8C0785.30505@web.de","threadId":"22474","inReplyTo":"4b8c0420.5544f10a.2eb2.ffffb4c4@mx.google.com","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-01T18:29:25Z","receivedAt":"2010-03-01T18:29:25Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> Markus Elfring's goal (I think) is to associate local modifications with\n> a particular branch, *not* carry them across branches; that is, the goal\n> is to stash local modifications away when we leave a branch and only pop\n> them off the stash when we RETURN to that same branch.\n\nYou are right. - I am especially interested in this use case.\n\nI would like to stress the relationships of files for a specific software\ndevelopment task\n\nRegards,\nMarkus\n"},{"id":"135967","messageId":"7vk4tvsu6x.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"4b8c0420.5544f10a.2eb2.ffffb4c4@mx.google.com","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-01T19:44:38Z","receivedAt":"2010-03-01T19:44:38Z","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> Markus Elfring's goal (I think) is to associate local modifications with\n> a particular branch, *not* carry them across branches;\n\nYou fooled me by having \"stash pop\" in the same script after you wrote\n'git checkout \"$@\"' to switch branches.  If you want to have per-branch\nstash, that is a totally independent problem, and I'd suggest using real\nrefs ($GIT_DIR/refs/stashes/$branch_name) instead of the md5 hack, if that\nis the motivation.\n"},{"id":"135974","messageId":"4B8C2F90.8080104@web.de","threadId":"22474","inReplyTo":"7vk4tvsu6x.fsf@alter.siamese.dyndns.org","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-01T21:20:16Z","receivedAt":"2010-03-01T21:20:16Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> If you want to have per-branch stash, that is a totally independent problem,\n> and I'd suggest using real refs ($GIT_DIR/refs/stashes/$branch_name) instead\n> of the md5 hack, if that is the motivation.\n\nHow is this use case different from the other?\nWhich \"problem\" have you got in mind?\n\nRegards,\nMarkus\n"},{"id":"135996","messageId":"b4087cc51003011741w29023914wec78f9acd6efb516@mail.gmail.com","threadId":"22474","inReplyTo":"4B8C2F90.8080104@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2010-03-02T01:41:50Z","receivedAt":"2010-03-02T01:41:50Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"On Mon, Mar 1, 2010 at 15:20, Markus Elfring <Markus.Elfring@web.de> wrote:\n>\n> How is this use case different from the other?\n\nThe other use case is the one that git already assumes to be popular:\nPeople want local modifications to remain in place across branch\ncheckouts.\n\n> Which \"problem\" have you got in mind?\n\nThe \"git checkout\" command is designed to carry local modifications\nacross branches transparently; when it's not so clear that such\ntransparency is possible, \"git checkout\" refuses to continue unless\nthe \"-m\" flag is used to try a 3-way merge involving:\n\n  * the local modifications.\n  * the files in the branch being left.\n  * the files in the branch being checked out.\n\nThis 3-way merge can get tricky if it ends in conflict, and so a smart\nuse of the stash in this process might help users untangle themselves.\n\nThat is what Junio has been thinking about in this thread.\n"},{"id":"136001","messageId":"4B8CDBCA.4030101@web.de","threadId":"22474","inReplyTo":"b4087cc51003011741w29023914wec78f9acd6efb516@mail.gmail.com","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-02T09:35:06Z","receivedAt":"2010-03-02T09:35:06Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> The other use case is the one that git already assumes to be popular:\n> People want local modifications to remain in place across branch checkouts.\n\nAre there software developers (besides me) who would like to work in the\nopposite way on demand?\n\nHow are the chances to make unfinished and uncommitted content updates sticky\nfor a particular branch (or a selection of branches) so that changes will not be\nmixed more as it will be really required for an editing task?\n\n\n> The \"git checkout\" command is designed to carry local modifications\n> across branches transparently;\n\nWhich wording will be preferred to \"reflect\" this fact in the manual and other\ndocumentation?\n\nRegards,\nMarkus\n"},{"id":"136002","messageId":"4B8CDE20.8030600@web.de","threadId":"22474","inReplyTo":"4b8c0420.5544f10a.2eb2.ffffb4c4@mx.google.com","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-02T09:45:04Z","receivedAt":"2010-03-02T09:45:04Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> You've still got the wrong problem in your head (though you're\n> solving a more useful issue).\n\nWhich idea would be better?\n\nRegards,\nMarkus\n"},{"id":"136031","messageId":"7vvdde62ai.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"4B8CDBCA.4030101@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-02T17:50:29Z","receivedAt":"2010-03-02T17:50:29Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Markus Elfring <Markus.Elfring@web.de> writes:\n\n> How are the chances to make unfinished and uncommitted content updates sticky\n> for a particular branch (or a selection of branches) so that changes will not be\n> mixed more as it will be really required for an editing task?\n\nTraditionally the right way to do this has been to make a temporary commit\non the branch, i.e.\n\n    $ git checkout topic\n    work work work... yikes, I cannot get this working\n    $ git commit -a -m 'wip: does not work yet' ;# temporary commit\n    $ git checkout other-topic\n    work work work....\n    $ git checkout topic\n    $ git reset --soft HEAD^ ;# drop the temporary commit\n\nI didn't re-read our documentation set for some time, but don't we teach\nthis anymore?\n"},{"id":"136032","messageId":"7v1vg261l1.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"4B8CDE20.8030600@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-02T18:05:46Z","receivedAt":"2010-03-02T18:05:46Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Markus Elfring <Markus.Elfring@web.de> writes:\n\n>> You've still got the wrong problem in your head (though you're\n>> solving a more useful issue).\n>\n> Which idea would be better?\n\nThey are different problems, and I don't think there is no \"better\"\nbetween them.  Is a squirrel 48% juicier than an orange?\n"},{"id":"136080","messageId":"4B8E8677.8060003@web.de","threadId":"22474","inReplyTo":"7vvdde62ai.fsf@alter.siamese.dyndns.org","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-03T15:55:35Z","receivedAt":"2010-03-03T15:55:35Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> Traditionally the right way to do this has been to make a temporary commit\n> on the branch, i.e.\n\nI would like to avoid such commits for unfinished content updates. Should the\nstorage operation be provided by the stash instead for intermediate work results?\nWill it happen to forget corresponding clean-up for \"temporary\" changes that\nmight be committed too early just to get them stored?\n\nRegards,\nMarkus\n"},{"id":"136081","messageId":"4B8E8790.6020709@web.de","threadId":"22474","inReplyTo":"7v1vg261l1.fsf@alter.siamese.dyndns.org","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-03T16:00:16Z","receivedAt":"2010-03-03T16:00:16Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> They are different problems, and I don't think there is no \"better\"\n> between them.\n\nWhich two use cases do we try to distinguish here?\n\nRegards,\nMarkus\n"},{"id":"136139","messageId":"b4087cc51003032346o4e8f338ub703c460e33c3f1e@mail.gmail.com","threadId":"22474","inReplyTo":"4B8E8677.8060003@web.de","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2010-03-04T07:46:18Z","receivedAt":"2010-03-04T07:46:18Z","isPatch":false,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"On Wed, Mar 3, 2010 at 09:55, Markus Elfring <Markus.Elfring@web.de> wrote:\n>> Traditionally the right way to do this has been to make a temporary commit\n>> on the branch, i.e.\n>\n> I would like to avoid such commits for unfinished content updates. Should the\n> storage operation be provided by the stash instead for intermediate work results?\n> Will it happen to forget corresponding clean-up for \"temporary\" changes that\n> might be committed too early just to get them stored?\n\nJunio,\n\nI'm not sure how often WIP commits become accidentally published or\nleft in the history, but perhaps it would be advantageous to provide a\nmeans of specifying officially that a particular commit is in fact a\nWIP commit such that no other commits can be made on top of this WIP\ncommit and it can't be merged with other branches or pushed or\nwhatever.\n"},{"id":"136166","messageId":"4B901026.4090002@web.de","threadId":"22474","inReplyTo":"b4087cc51003032346o4e8f338ub703c460e33c3f1e@mail.gmail.com","subject":"Re: Better cooperation between checkouts and stashing","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-04T19:55:18Z","receivedAt":"2010-03-04T19:55:18Z","isPatch":false,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> I'm not sure how often WIP commits become accidentally published or\n> left in the history, but perhaps it would be advantageous to provide\n> a means of specifying officially that a particular commit is in fact\n> a WIP commit such that no other commits can be made on top of this WIP\n> commit and it can't be merged with other branches or pushed or whatever.\n\nWhen will such blocking commits be useful?\nWould you really like to support a stopper or barrier for branches?\n\nRegards,\nMarkus\n"},{"id":"137033","messageId":"4BA104C7.5020207@web.de","threadId":"22474","inReplyTo":"4b8bf32f.0706c00a.26cb.691d@mx.google.com","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-17T16:35:19Z","receivedAt":"2010-03-17T16:35:19Z","isPatch":true,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":">From 828d97e2f50b49c87138f382d579605dc134d8ca Mon Sep 17 00:00:00 2001\nFrom: Markus Elfring <Markus.Elfring@web.de>\nDate: Wed, 17 Mar 2010 17:05:08 +0100\nSubject: [PATCH] Documentation: clarification for the command \"git checkout <branch>\"\n\nThe software implementation worked differently in comparison\nto the description in the first paragraph. The updated explanation\nshould reflect the current behaviour.\n\nSigned-off-by: Markus Elfring <Markus.Elfring@web.de>\n---\n\n> I think it would be a great contribution if you could clean up\n> Junio's explanation and submit a patch that includes it in the\n> documentation for \"git checkout\".\n\nWill the following wording be acceptable?\n\nRegards,\nMarkus\n\n\n Documentation/git-checkout.txt |    9 +++++----\n 1 files changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex 37c1810..5fcea56 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -15,10 +15,11 @@ SYNOPSIS\n \n DESCRIPTION\n -----------\n-\n-When <paths> are not given, this command switches branches by\n-updating the index, working tree, and HEAD to reflect the specified\n-branch.\n+When <paths> are not given, this command marks the specified branch\n+as the next commit target. (The reference \"HEAD\" points to its tip.)\n+Checking out another branch (branch switching) is designed to carry\n+your local modifications across with you. The working tree is not\n+restored to the state of its last commit.\n \n If `-b` is given, a new branch is created and checked out, as if\n linkgit:git-branch[1] were called; in this case you can\n-- \n1.7.0.1\n"},{"id":"137035","messageId":"32541b131003170944w7a0215frcace205f32d313bf@mail.gmail.com","threadId":"22474","inReplyTo":"4BA104C7.5020207@web.de","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Avery Pennarun","fromEmail":"apenwarr@gmail.com","sentAt":"2010-03-17T16:44:52Z","receivedAt":"2010-03-17T16:44:52Z","isPatch":true,"sender":{"key":"apenwarr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/20592?v=4"},"body":"On Wed, Mar 17, 2010 at 12:35 PM, Markus Elfring <Markus.Elfring@web.de> wrote:\n> -When <paths> are not given, this command switches branches by\n> -updating the index, working tree, and HEAD to reflect the specified\n> -branch.\n> +When <paths> are not given, this command marks the specified branch\n> +as the next commit target. (The reference \"HEAD\" points to its tip.)\n> +Checking out another branch (branch switching) is designed to carry\n> +your local modifications across with you. The working tree is not\n> +restored to the state of its last commit.\n>\n>  If `-b` is given, a new branch is created and checked out, as if\n>  linkgit:git-branch[1] were called; in this case you can\n\nThe new version spends all the time talking about weird exceptions and\nnone of the time actually saying what the basic functionality is\nsupposed to be.  How about this:\n\n--\nWhen <paths> are not given, this command switches from your current\nbranch to the given branch.  This is done by updating HEAD to point at\nthe given branch, reading the new branch's content into the index, and\nchecking out the content into your working tree.  Where possible, any\nfiles you have modified in your current working tree or index remain\nmodified in the newly-checked-out branch.  This cannot be done,\nhowever, when those modified files differ between the old and new\nbranches, in which case the checkout will abort in order to avoid\nlosing your changes.  You might want to use 'git stash' in this case.\n--\n\nHave fun,\n\nAvery\n"},{"id":"137038","messageId":"4BA10AAF.9050907@web.de","threadId":"22474","inReplyTo":"32541b131003170944w7a0215frcace205f32d313bf@mail.gmail.com","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-17T17:00:31Z","receivedAt":"2010-03-17T17:00:31Z","isPatch":true,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> This is done by updating HEAD to point at the given branch,\n\nIs it supposed that Git users should know from other information sources \nalready what the key word \"HEAD\" means?\n\nRegards,\nMarkus\n"},{"id":"137043","messageId":"7vaau6q18q.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"32541b131003170944w7a0215frcace205f32d313bf@mail.gmail.com","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-17T17:58:13Z","receivedAt":"2010-03-17T17:58:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Avery Pennarun <apenwarr@gmail.com> writes:\n\n> On Wed, Mar 17, 2010 at 12:35 PM, Markus Elfring <Markus.Elfring@web.de> wrote:\n>> -When <paths> are not given, this command switches branches by\n>> -updating the index, working tree, and HEAD to reflect the specified\n>> -branch.\n> ...\n> The new version spends all the time talking about weird exceptions and\n> none of the time actually saying what the basic functionality is\n> supposed to be.  How about this:\n>\n> --\n> When <paths> are not given, this command switches from your current\n> branch to the given branch.  This is done by updating HEAD to point at\n> the given branch, reading the new branch's content into the index, and\n> checking out the content into your working tree.  Where possible, any\n> files you have modified in your current working tree or index remain\n> modified in the newly-checked-out branch.  This cannot be done,\n> however, when those modified files differ between the old and new\n> branches, in which case the checkout will abort in order to avoid\n> losing your changes.  You might want to use 'git stash' in this case.\n> --\n\nI like the \"First state what it conceptually does and for what purpose it\nis used.\", but isn't this going down to too low-level details without\nsaying what these low-level details mean to the visible effects?\n\nWhen <paths> are not given, this command makes the named branch the\ncurrent branch, so that a further work will be committed on that branch.\n\nThe index and the working tree are updated to the contents of the new\nbranch, while carrying the uncommitted changes you made so far along with\nyou.  If you made changes to paths that are different from the current\nbranch and the new branch, the command will stop you in order to prevent\nyou from losing your uncommited changes in potential conflicts between\nthem and the changes between two branches.  You may want retry the command\nafter recording the local changes (1) in a temporary commit on the current\nbranch, or (2) by using \"git stash\".  Alternatively, see \"-m\" option.\n"},{"id":"137046","messageId":"4BA11D8C.5020007@web.de","threadId":"22474","inReplyTo":"7vaau6q18q.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-17T18:21:00Z","receivedAt":"2010-03-17T18:21:00Z","isPatch":true,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":">      If you made changes to paths that are different from the current\n> branch and the new branch, the command will stop you in order to prevent\n> you from losing your uncommited changes in potential conflicts between\n> them and the changes between two branches.\n\nI find it hard to realise what will be inside or outside of a path structure\nunder the mentioned conditions.\n\nRegards,\nMarkus\n"},{"id":"137047","messageId":"7v8w9qkd5z.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"4BA11D8C.5020007@web.de","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-17T18:37:12Z","receivedAt":"2010-03-17T18:37:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Markus Elfring <Markus.Elfring@web.de> writes:\n\n>>      If you made changes to paths that are different from the current\n>> branch and the new branch, the command will stop you in order to prevent\n>> you from losing your uncommited changes in potential conflicts between\n>> them and the changes between two branches.\n>\n> I find it hard to realise what will be inside or outside of a path structure\n> under the mentioned conditions.\n\nSorry, but I didn't say anything about path structure, and I am unsure\nwhat you were talking about.  Here is what I meant:\n\nImagine you are on branch A and trying to switch to branch B.  There are\nchanged paths between these two branches (i.e. the paths that appear in\nthe output from \"git diff --name-only A B\") and there are unchanged paths.\nIf you have local changes to the former, such local changes may conflict\nwith the change made between A and B, and stops the command.\n"},{"id":"137050","messageId":"b4087cc51003171150g303cf1c0uf2e0227594eef3fc@mail.gmail.com","threadId":"22474","inReplyTo":"7v8w9qkd5z.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2010-03-17T18:50:15Z","receivedAt":"2010-03-17T18:50:15Z","isPatch":true,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"On Wed, Mar 17, 2010 at 13:37, Junio C Hamano <gitster@pobox.com> wrote:\n> such local changes may conflict with the change\n> made between A and B, and stops the command.\n\nI'm sensing that it needs to be clarified what a conflict is.\n"},{"id":"137054","messageId":"7vfx3yiwgm.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"b4087cc51003171150g303cf1c0uf2e0227594eef3fc@mail.gmail.com","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-17T19:23:21Z","receivedAt":"2010-03-17T19:23:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Michael Witten <mfwitten@gmail.com> writes:\n\n> On Wed, Mar 17, 2010 at 13:37, Junio C Hamano <gitster@pobox.com> wrote:\n>> such local changes may conflict with the change\n>> made between A and B, and stops the command.\n>\n> I'm sensing that it needs to be clarified what a conflict is.\n\nHmm, a conflict is \"you changed it in one way, and I am trying to change\nthe same thing in another way, you two have to fight it out\".  What other\ninterpretations are there, especially in a context of SCM?\n\nI wouldn't mind a patch to add the definition to glossary, though.\n"},{"id":"137077","messageId":"4BA1FC39.10300@web.de","threadId":"22474","inReplyTo":"7vaau6q18q.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-18T10:11:05Z","receivedAt":"2010-03-18T10:11:05Z","isPatch":true,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> You may want retry the command after recording the local changes\n> (1) in a temporary commit on the current branch,\n\nCan commits be consistently marked for intermediate use?\nCan such \"special\" commits be easily found later on?\n\n\n> or (2) by using \"git stash\".\n\nIs this storage operation supported per branch?\nDoes a checkout look if any files were stashed away for the specified branch before?\n\nRegards,\nMarkus\n"},{"id":"137103","messageId":"32541b131003180936x746dad06k386788d3cb6fcdeb@mail.gmail.com","threadId":"22474","inReplyTo":"4BA1FC39.10300@web.de","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Avery Pennarun","fromEmail":"apenwarr@gmail.com","sentAt":"2010-03-18T16:36:17Z","receivedAt":"2010-03-18T16:36:17Z","isPatch":true,"sender":{"key":"apenwarr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/20592?v=4"},"body":"On Thu, Mar 18, 2010 at 6:11 AM, Markus Elfring <Markus.Elfring@web.de> wrote:\n>> You may want retry the command after recording the local changes\n>> (1) in a temporary commit on the current branch,\n>\n> Can commits be consistently marked for intermediate use?\n> Can such \"special\" commits be easily found later on?\n\nYou just make the commit with a 'FIXME' type commit message, then 'git\ncommit --amend' to fix it when you come back later.\n\n>> or (2) by using \"git stash\".\n>\n> Is this storage operation supported per branch?\n> Does a checkout look if any files were stashed away for the specified branch before?\n\nstashing isn't really something you'd want to do on a per-branch\nbasis.  Most of the point is that you stash away your changes, then\nswitch to another branch, then restore your stash to your *current*\nworking state sometime later.\n\nHave fun,\n\nAvery\n"},{"id":"137104","messageId":"b4087cc51003181019r4408953bxcd5049c9521b8173@mail.gmail.com","threadId":"22474","inReplyTo":"32541b131003180936x746dad06k386788d3cb6fcdeb@mail.gmail.com","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Michael Witten","fromEmail":"mfwitten@gmail.com","sentAt":"2010-03-18T17:19:13Z","receivedAt":"2010-03-18T17:19:13Z","isPatch":true,"sender":{"key":"mfwitten@gmail.com","avatar":"https://avatars.githubusercontent.com/u/597101?v=4"},"body":"On Thu, Mar 18, 2010 at 11:36, Avery Pennarun <apenwarr@gmail.com> wrote\n> On Thu, Mar 18, 2010 at 6:11 AM, Markus Elfring <Markus.Elfring@web.de> wrote:\n>>> You may want retry the command after recording the local changes\n>>> (1) in a temporary commit on the current branch,\n>>\n>> Can commits be consistently marked for intermediate use?\n>> Can such \"special\" commits be easily found later on?\n>\n> You just make the commit with a 'FIXME' type commit message, then 'git\n> commit --amend' to fix it when you come back later.\n\nSomething more explicit might be useful in my opinion, as suggested in\nthis previous post:\n\n    http://marc.info/?l=git&m=126768880311121&w=2\n\n    > I'm not sure how often WIP commits become\n    > accidentally published or left in the history,\n    > but perhaps it would be advantageous to\n    > provide a means of specifying officially that\n    > a particular commit is in fact a WIP commit\n    > such that no other commits can be made on top\n    > of this WIP commit and it can't be merged with\n    > other branches or pushed or whatever.\n\n>>> or (2) by using \"git stash\".\n>>\n>> Is this storage operation supported per branch?\n>> Does a checkout look if any files were stashed away for the specified branch before?\n\nMarkus, this was discussed ad nauseum in the other thread:\n\n    http://marc.info/?l=git&m=126746296820948&w=2\n\n    http://marc.info/?l=git&m=126749413508313&w=2\n\n    http://marc.info/?l=git&m=126746730431007&w=2\n\nAre you not reading? Are you not comprehending? Are you trolling?\n\n> stashing isn't really something you'd want to do on a per-branch\n> basis.  Most of the point is that you stash away your changes, then\n> switch to another branch, then restore your stash to your *current*\n> working state sometime later.\n\nAs you may know, \"git checkout\" carries local modifications to the new\nworking tree if there are no conflicts, so no explicit stash usage is\nnecessary in many cases.\n\nAnyway, I think it would be useful to be able to manage multiple\nstashes rather than having to rely on just one global stash. However,\nI imagine than explicit Work In Progress (WIP) commits as sketched\nabove would go a long way in keeping histories and workflows clean and\norganized.\n"},{"id":"137106","messageId":"32541b131003181033p7916d92frc1269b95c292e3db@mail.gmail.com","threadId":"22474","inReplyTo":"b4087cc51003181019r4408953bxcd5049c9521b8173@mail.gmail.com","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Avery Pennarun","fromEmail":"apenwarr@gmail.com","sentAt":"2010-03-18T17:33:18Z","receivedAt":"2010-03-18T17:33:18Z","isPatch":true,"sender":{"key":"apenwarr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/20592?v=4"},"body":"On Thu, Mar 18, 2010 at 1:19 PM, Michael Witten <mfwitten@gmail.com> wrote:\n> On Thu, Mar 18, 2010 at 11:36, Avery Pennarun <apenwarr@gmail.com> wrote\n>> stashing isn't really something you'd want to do on a per-branch\n>> basis.  Most of the point is that you stash away your changes, then\n>> switch to another branch, then restore your stash to your *current*\n>> working state sometime later.\n>\n> As you may know, \"git checkout\" carries local modifications to the new\n> working tree if there are no conflicts, so no explicit stash usage is\n> necessary in many cases.\n\nI'm almost never lucky enough that switching branches won't touch the\nsame files as the ones I've been editing (especially Makefile).  I\nimagine this works better with larger repositories like the Linux\nkernel.  But my fingers have learned that if I do 'git stash' it\nalways works, while if I don't it doesn't always work, so I stash\nwithout thinking nowadays.\n\nThe other big advantage of using stash is that your half-done files\nend up in the repo, so if you later screw up by doing something\nidiotic like 'git reset --hard' at the wrong time, you can still get\nit back.  I love that feeling of safety.\n\n> Anyway, I think it would be useful to be able to manage multiple\n> stashes rather than having to rely on just one global stash. However,\n> I imagine than explicit Work In Progress (WIP) commits as sketched\n> above would go a long way in keeping histories and workflows clean and\n> organized.\n\nThe stash can contain multiple entries.  They're stored in a stack,\nbut you can pull prior entries out of the stack if you want.\nPersonally, I don't need anything more.\n\nHave fun,\n\nAvery\n"},{"id":"137188","messageId":"4BA3329E.6050304@web.de","threadId":"22474","inReplyTo":"b4087cc51003181019r4408953bxcd5049c9521b8173@mail.gmail.com","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-19T08:15:26Z","receivedAt":"2010-03-19T08:15:26Z","isPatch":true,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> Are you not reading? Are you not comprehending? Are you trolling?\n\nI answer these three questions with \"NO\".\n\nI find that the discussion is not finished yet. It was not achieved a common\nconclusion and consensus on all mentioned details so far.\n\n\n>> stashing isn't really something you'd want to do on a per-branch\n>> basis.  Most of the point is that you stash away your changes, then\n>> switch to another branch, then restore your stash to your *current*\n>> working state sometime later.\n\nI have got different expectations. I would expect that there are enough\nintermediate work results available to justify a stash per branch so that\nunwanted \"temporary\" or \"throw-away\" commits can be avoided.\n\n\n> As you may know, \"git checkout\" carries local modifications to the new\n> working tree if there are no conflicts, so no explicit stash usage is\n> necessary in many cases.\n\nVarious software projects have got different amounts of uncommitted changes\nbetween branches.\n\n\n> Anyway, I think it would be useful to be able to manage multiple\n> stashes rather than having to rely on just one global stash. However,\n> I imagine than explicit Work In Progress (WIP) commits as sketched\n> above would go a long way in keeping histories and workflows clean\n> and organized.\n\nI am also interested in improvements for this feature request. Does a \"WIP\"\nreally need a commit to get the unfinished changes stored?\n\nRegards,\nMarkus\n"},{"id":"137189","messageId":"4BA335B6.4000103@web.de","threadId":"22474","inReplyTo":"32541b131003181033p7916d92frc1269b95c292e3db@mail.gmail.com","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-19T08:28:38Z","receivedAt":"2010-03-19T08:28:38Z","isPatch":true,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> The stash can contain multiple entries.  They're stored in a stack,\n> but you can pull prior entries out of the stack if you want.\n\nI am missing a semantic relationship of the stashed files to the work that they\nbelong to in various branches. I would appreciate to see a clear connection\nbetween them.\n\nRegards,\nMarkus\n"},{"id":"137246","messageId":"32541b131003191017rdc4e87fgcc4fabc76e0709be@mail.gmail.com","threadId":"22474","inReplyTo":"4BA335B6.4000103@web.de","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Avery Pennarun","fromEmail":"apenwarr@gmail.com","sentAt":"2010-03-19T17:17:35Z","receivedAt":"2010-03-19T17:17:35Z","isPatch":true,"sender":{"key":"apenwarr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/20592?v=4"},"body":"On Fri, Mar 19, 2010 at 4:28 AM, Markus Elfring <Markus.Elfring@web.de> wrote:\n>> The stash can contain multiple entries.  They're stored in a stack,\n>> but you can pull prior entries out of the stack if you want.\n>\n> I am missing a semantic relationship of the stashed files to the work that they\n> belong to in various branches. I would appreciate to see a clear connection\n> between them.\n\nThen what you want is just a temporary commit.\n\nI think your mental model has exaggerated the cost of a commit.\nCommits cost almost exactly zero.\n\n    git commit -a -m 'FIXME temporary'\n\nAnd there you have it.  When you want to undo the commit or update it,\nyou just do\n\n    git reset HEAD^\n\nand it's as if the commit never happened.  Or don't reset, but just\nmake further changes and replace the commit:\n\n    git commit -a --amend\n\nWhich part isn't acceptable?\n\nHave fun,\n\nAvery\n"},{"id":"137311","messageId":"4BA46469.7020800@web.de","threadId":"22474","inReplyTo":"32541b131003191017rdc4e87fgcc4fabc76e0709be@mail.gmail.com","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-20T06:00:09Z","receivedAt":"2010-03-20T06:00:09Z","isPatch":true,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> Commits cost almost exactly zero.\n\nThe storage costs are negligible. I am more concerned about unwanted work flow\neffects because a modification might be committed and suddenly merged too early.\n\n\n>     git commit -a -m 'FIXME temporary'\n\nThe specified message is not independent from a language. I see also a potential\nfor typos by this approach which will make it harder to distinguish\nnon-temporary commits from the real ones.\n\nRegards,\nMarkus\n"},{"id":"138186","messageId":"4BB21F6D.7070804@web.de","threadId":"22474","inReplyTo":"4BA3329E.6050304@web.de","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-03-30T15:57:33Z","receivedAt":"2010-03-30T15:57:33Z","isPatch":true,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> I find that the discussion is not finished yet. It was not achieved a common\n> conclusion and consensus on all mentioned details so far.\n\nCan we achieve progress for an update of the manual?\n\nRegards,\nMarkus\n"},{"id":"138222","messageId":"7vd3ylv4oq.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"4BB21F6D.7070804@web.de","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-03-30T22:13:25Z","receivedAt":"2010-03-30T22:13:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Markus Elfring <Markus.Elfring@web.de> writes:\n\n>> I find that the discussion is not finished yet. It was not achieved a common\n>> conclusion and consensus on all mentioned details so far.\n>\n> Can we achieve progress for an update of the manual?\n>\n> Regards,\n> Markus\n\nSomething like this?\n\n Documentation/git-checkout.txt |   27 ++++++++++++++++++++++++---\n 1 files changed, 24 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex 37c1810..d443a12 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -16,9 +16,9 @@ SYNOPSIS\n DESCRIPTION\n -----------\n \n-When <paths> are not given, this command switches branches by\n-updating the index, working tree, and HEAD to reflect the specified\n-branch.\n+When <paths> are not given, this command makes the named branch the\n+current branch, so that a further work will be committed on that branch.\n+See \"Switching Branches\" below.\n \n If `-b` is given, a new branch is created and checked out, as if\n linkgit:git-branch[1] were called; in this case you can\n@@ -149,6 +149,27 @@ checks out the branch (instead of detaching).  You may also specify\n \tthe index will be used.\n \n \n+Switching Branches\n+------------------\n+\n+While switching to another branch (or more in general, to another commit\n+that is not the current commit), the index and the working tree are\n+updated to the contents of the new branch, while carrying the uncommitted\n+changes you made so far along with you.  People often start making changes\n+and then realize that the changes belong to a branch that is different\n+from the current one, and it helps these people to carry the changes\n+forward upon switching branches.\n+\n+If the branch you are switching to has one version of a file, and the\n+current branch has a different version of it, which you changed in your\n+working tree to yet another version, carrying the changes forward is not\n+possible without merging.  But you may not be ready to resolve such\n+conflicts right now.  By default, the command refuses to switch branches\n+to prevent you from losing your local changes due to such conflicts.  In\n+such a case, you may want retry the command after recording the local\n+changes (1) in a temporary commit on the current branch, or (2) by using\n+\"git stash\".  Alternatively, use \"-m\" option to force a merge.\n+\n \n Detached HEAD\n -------------\n"},{"id":"138257","messageId":"p2nf3271551003302058ve6b54731h1bea42b5c6605928@mail.gmail.com","threadId":"22474","inReplyTo":"7vd3ylv4oq.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2010-03-31T03:58:20Z","receivedAt":"2010-03-31T03:58:20Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"Hi,\n\nOn Wed, Mar 31, 2010 at 3:43 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> +such a case, you may want retry the command after recording the local\n> +changes (1) in a temporary commit on the current branch, or (2) by using\n> +\"git stash\".  Alternatively, use \"-m\" option to force a merge.\n\nCouple of things: Is (1) really an option? The user will have to go\nthrough documentation on rewriting history, which I find completely\nunnecessary to just switch branches. Second, you might want to mention\na \"git stash apply\" and include a reference to git-stash\ndocumentation.\n\n-- Ram\n"},{"id":"138318","messageId":"7vd3yjsriz.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"p2nf3271551003302058ve6b54731h1bea42b5c6605928@mail.gmail.com","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-01T04:52:52Z","receivedAt":"2010-04-01T04:52:52Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ramkumar Ramachandra <artagnon@gmail.com> writes:\n\n> On Wed, Mar 31, 2010 at 3:43 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> +such a case, you may want retry the command after recording the local\n>> +changes (1) in a temporary commit on the current branch, or (2) by using\n>> +\"git stash\". Alternatively, use \"-m\" option to force a merge.\n>\n> Couple of things: Is (1) really an option?\n\nOf course; otherwise I wouldn't have written it, but another option (0)\nwould be:\n\n    (0) if you are in the middle of working something for the current\n    branch, finish it first before switching to other task.\n\nBut that would go without saying.\n\n> The user will have to go\n> through documentation on rewriting history, which I find completely\n> unnecessary to just switch branches.\n\nI think you are thinking backwards.  If the user always does a perfect job\nbefore making each and every commit, she doesn't ever need to learn\n\"amend\".  Otherwise, she will learn \"amend\" way before learning to switch\nbetween branches to work on different things at the same time.\n\nIOW, by the time the user learns branch switching, I expect she at least\nknows about \"amend\" (if not rebase-i/filter-branch), and that is all that\nis necessary to restart from a WIP commit when she comes back.\n"},{"id":"138330","messageId":"4BB43F7C.8070003@web.de","threadId":"22474","inReplyTo":"7vd3ylv4oq.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-04-01T06:38:52Z","receivedAt":"2010-04-01T06:38:52Z","isPatch":true,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> In such a case, you may want retry the command after recording\n> the local changes (1) in a temporary commit on the current branch,\n\nShould corresponding work flow actions be also mentioned to clean up such\n\"temporaries\"?\n\n\n> or (2) by using \"git stash\".\n\nDo we need a new feature \"stash per branch\" here?\n\nWill an option be useful to specify that uncommitted changes can be overwritten\nby data from the branch switch?\n\nRegards,\nMarkus\n"},{"id":"138339","messageId":"x2zf3271551004010609l9edc6bf3jc9e8b70daca63f37@mail.gmail.com","threadId":"22474","inReplyTo":"7vd3yjsriz.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Ramkumar Ramachandra","fromEmail":"artagnon@gmail.com","sentAt":"2010-04-01T13:09:24Z","receivedAt":"2010-04-01T13:09:24Z","isPatch":true,"sender":{"key":"r@artagnon.com","avatar":"https://avatars.githubusercontent.com/u/37226?v=4"},"body":"> I think you are thinking backwards.  If the user always does a perfect job\n> before making each and every commit, she doesn't ever need to learn\n> \"amend\".  Otherwise, she will learn \"amend\" way before learning to switch\n> between branches to work on different things at the same time.\n\nRight. Got it. It's pretty difficult to think from a new user's\nperspective actually :)\n\n-- Ram\n"},{"id":"139149","messageId":"4BC07D81.6040402@web.de","threadId":"22474","inReplyTo":"7vd3ylv4oq.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Markus Elfring","fromEmail":"markus.elfring@web.de","sentAt":"2010-04-10T13:30:41Z","receivedAt":"2010-04-10T13:30:41Z","isPatch":true,"sender":{"key":"markus.elfring@web.de","avatar":null},"body":"> Something like this?\n\nWhich update will be published for the manual?\n\nRegards,\nMarkus\n"},{"id":"139209","messageId":"7vhbnjuegl.fsf@alter.siamese.dyndns.org","threadId":"22474","inReplyTo":"4BC07D81.6040402@web.de","subject":"Re: [PATCH] Clarification for the command \"git checkout <branch>\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2010-04-10T22:31:38Z","receivedAt":"2010-04-10T22:31:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Markus Elfring <Markus.Elfring@web.de> writes:\n\n>> Something like this?\n>\n> Which update will be published for the manual?\n\nNeither one without any clear support by reviews on the list.  You asked\n\n    Markus Elfring <Markus.Elfring@web.de> writes:\n\n    >> I find that the discussion is not finished yet. It was not achieved a common\n    >> conclusion and consensus on all mentioned details so far.\n    >\n    > Can we achieve progress for an update of the manual?\n\nand the patch was only to illustrate what _you_ could do to help the\ntopic.\n\nIOW, the message you are responding to is a \"Yes you could help it by\ndoing something like this and asking for comments\" in response to \"Can we\nachieve progress?\"\n"}]}