{"thread":{"id":"12787","subject":"Switching branches without committing changes","startedAt":"2008-03-21T03:27:09Z","lastAt":"2008-03-24T19:07:11Z","messageCount":10,"participants":["Joe Fiorini","Jeff King","Shawn O. Pearce","Junio C Hamano","Xavier Maillard"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"72554","messageId":"A17C3E8C-3D0E-41B4-8A43-37EC8C3F55C2@faithfulgeek.org","threadId":"12787","inReplyTo":null,"subject":"Switching branches without committing changes","fromName":"Joe Fiorini","fromEmail":"joe@faithfulgeek.org","sentAt":"2008-03-21T03:27:09Z","receivedAt":"2008-03-21T03:27:09Z","isPatch":false,"sender":{"key":"joe@faithfulgeek.org","avatar":null},"body":"He all,\n\nI'm still a newbie to Git (and this list), so if I don't provide  \nenough details please let me know what you need and I will provide :).\n\nI'm trying to switch branches without committing my changes.  Is this  \npossible?  For example, I'm working on a site, I'm testing the  \nimplementation of a new technology (branch B), I'm not quite done  \nthere (or I forget to commit everything) and I want to implement  \nsomething else new.  I create a new branch off of B, called B.1, and  \nthen make some changes.  I commit only the changes that apply to B.1  \nand then try to go back to B.  However, I get an error saying a file I  \nchanged in B is not uptodate and it cannot merge.  What am I doing  \nwrong and how can I get back to B?\n\nThanks all!\nJoe\n"},{"id":"72555","messageId":"20080321035209.GA2169@coredump.intra.peff.net","threadId":"12787","inReplyTo":"A17C3E8C-3D0E-41B4-8A43-37EC8C3F55C2@faithfulgeek.org","subject":"Re: Switching branches without committing changes","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-03-21T03:52:09Z","receivedAt":"2008-03-21T03:52:09Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Mar 20, 2008 at 11:27:09PM -0400, Joe Fiorini wrote:\n\n> I'm trying to switch branches without committing my changes.  Is this  \n> possible?  For example, I'm working on a site, I'm testing the  \n> implementation of a new technology (branch B), I'm not quite done there \n> (or I forget to commit everything) and I want to implement something else \n> new.  I create a new branch off of B, called B.1, and then make some \n> changes.  I commit only the changes that apply to B.1 and then try to go \n> back to B.  However, I get an error saying a file I changed in B is not \n> uptodate and it cannot merge.  What am I doing wrong and how can I get \n> back to B?\n\nIt sounds like you still have some changes in your working tree, and\nthat is preventing the branch switch.\n\nGenerally you would have stashed those changes before working on the\nsecond task, like:\n\n  git checkout B\n  hack hack hack\n  # oops, I want to work on some other topic\n  git stash\n  git checkout -b B.1 B\n  hack hack hack\n  git commit\n  # now I'm ready to go back to my original work\n  git checkout B\n  git stash apply\n\nThat example uses git-stash, but you could just as easily do it with a\n\"work in progress\" commit on a branch (which is how people did it before\ngit-stash was written). Now in your case, I get the impression you have\ndone this:\n\n  git checkout B\n  hack hack hack\n  # oops, I want to work on some other topic\n  git checkout -b B.1 ;# keeps all of your changes in the working tree\n  hack hack hack\n  # now my second topic is ready for commit\n  git add ;# selectively, or with git add -p\n  git commit\n  # now I'm ready to go back to my original work\n  git checkout B\n\nbut the last checkout doesn't work cleanly, because you have some\nuncommitted changes in your working tree for some file 'A', but moving\nfrom B.1 to B would also change 'A'.\n\nSo you actually need to merge those changes (actually, you are merging\nthe _undo_ of the B.1 changes) to get back to B. Unfortunately,\ngit-checkout is smart enough to do merges that don't touch the same\nfile, but not anything more complex. So instead, we can use stash again.\nAt this point, you can do:\n\n  git stash\n  git checkout B\n  git stash apply\n\nwhich will actually invoke the \"real\" merge machinery to correctly sort\nout the changes.\n\nSo what you did isn't wrong, but you probably would have had a much\neasier time if you stashed _before_ doing the B.1 work. It would have\nmade your git-add easier, and it makes testing more accurate (since you\nnever actually tested the state committed to B.1; you tested B.1 + your\nchanges that will be commited on top of B).\n\nMake sense?\n\n-Peff\n"},{"id":"72556","messageId":"20080321040647.GE8410@spearce.org","threadId":"12787","inReplyTo":"A17C3E8C-3D0E-41B4-8A43-37EC8C3F55C2@faithfulgeek.org","subject":"Re: Switching branches without committing changes","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-03-21T04:06:47Z","receivedAt":"2008-03-21T04:06:47Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Joe Fiorini <joe@faithfulgeek.org> wrote:\n> I'm still a newbie to Git (and this list), so if I don't provide  \n> enough details please let me know what you need and I will provide :).\n> \n> I'm trying to switch branches without committing my changes.  Is this  \n> possible?  For example, I'm working on a site, I'm testing the  \n> implementation of a new technology (branch B), I'm not quite done  \n> there (or I forget to commit everything) and I want to implement  \n> something else new.  I create a new branch off of B, called B.1, and  \n> then make some changes.  I commit only the changes that apply to B.1  \n> and then try to go back to B.  However, I get an error saying a file I  \n> changed in B is not uptodate and it cannot merge.  What am I doing  \n> wrong and how can I get back to B?\n\nUse `git checkout -m` to switch the branch anyway.  However, if\nthere is a merge conflict while you are trying to carry the changes\nto the other branch you may be faced with a merge conflict you are\nnot prepared to resolve, or simply cannot resolve in a reasonable\nperiod of time.\n\nYou may want to use `git stash` to save your dirty changes off to\na safe area, then switch branches.  Your changes won't be there,\nbut you can get them back with `git stash apply 0`.  If things go\nbadly, you can go back to B.1 and use `git stash apply 0` to put\nthe changes back where they were, and figure out what you are going\nto do from there.\n\n-- \nShawn.\n"},{"id":"72557","messageId":"20080321041013.GA2502@coredump.intra.peff.net","threadId":"12787","inReplyTo":"20080321040647.GE8410@spearce.org","subject":"Re: Switching branches without committing changes","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-03-21T04:10:13Z","receivedAt":"2008-03-21T04:10:13Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Mar 21, 2008 at 12:06:47AM -0400, Shawn O. Pearce wrote:\n\n> Use `git checkout -m` to switch the branch anyway.  However, if\n> there is a merge conflict while you are trying to carry the changes\n> to the other branch you may be faced with a merge conflict you are\n> not prepared to resolve, or simply cannot resolve in a reasonable\n> period of time.\n\nAh, for some reason I didn't think of '-m' in the advice I gave (I guess\nI have just never used it). It is almost certainly simpler than using a\n'stash' at this point (but I do think stashing _beforehand_ still has\nadvantages).\n\n-Peff\n"},{"id":"72561","messageId":"0A5FD247-A09E-4E3A-8BB5-35F9390E7FB3@faithfulgeek.org","threadId":"12787","inReplyTo":"20080321041013.GA2502@coredump.intra.peff.net","subject":"Re: Switching branches without committing changes","fromName":"Joe Fiorini","fromEmail":"joe@faithfulgeek.org","sentAt":"2008-03-21T04:40:46Z","receivedAt":"2008-03-21T04:40:46Z","isPatch":false,"sender":{"key":"joe@faithfulgeek.org","avatar":null},"body":"Thanks for the replies.  I definitely like the stashing approach.  Is  \nthere any overhead or caveat to using stash a lot?\n\n-Joe\n\nOn Mar 21, 2008, at 12:10 AM, Jeff King wrote:\n\n> On Fri, Mar 21, 2008 at 12:06:47AM -0400, Shawn O. Pearce wrote:\n>\n>> Use `git checkout -m` to switch the branch anyway.  However, if\n>> there is a merge conflict while you are trying to carry the changes\n>> to the other branch you may be faced with a merge conflict you are\n>> not prepared to resolve, or simply cannot resolve in a reasonable\n>> period of time.\n>\n> Ah, for some reason I didn't think of '-m' in the advice I gave (I  \n> guess\n> I have just never used it). It is almost certainly simpler than  \n> using a\n> 'stash' at this point (but I do think stashing _beforehand_ still has\n> advantages).\n>\n> -Peff\n"},{"id":"72562","messageId":"7vod98u1pr.fsf@gitster.siamese.dyndns.org","threadId":"12787","inReplyTo":"20080321041013.GA2502@coredump.intra.peff.net","subject":"Re: Switching branches without committing changes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-03-21T04:42:56Z","receivedAt":"2008-03-21T04:42:56Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Fri, Mar 21, 2008 at 12:06:47AM -0400, Shawn O. Pearce wrote:\n>\n>> Use `git checkout -m` to switch the branch anyway.  However, if\n>> there is a merge conflict while you are trying to carry the changes\n>> to the other branch you may be faced with a merge conflict you are\n>> not prepared to resolve, or simply cannot resolve in a reasonable\n>> period of time.\n>\n> Ah, for some reason I didn't think of '-m' in the advice I gave (I guess\n> I have just never used it). It is almost certainly simpler than using a\n> 'stash' at this point (but I do think stashing _beforehand_ still has\n> advantages).\n\nThe thing is, that -m is really to mollify people who are _too_ accustomed\nto CVS/SVN update behaviour.  Over there, \"scm update\" does not give you\nany choice other than having to merge.\n\nWith git, stashing or creating Park commits are very cheap operation and\nunless you are reasonably sure that your local changes do not conflict\nwith the branch you are switching to, there is no strong reason to prefer\n\"checkout -m\".\n\nSwitching branches with dirty state can have three scenarios:\n\n (1) you are getting interrupted and your current local changes do not\n     belong to what you are going to commit after switching (e.g. \"the\n     boss says fix that right away\").\n\n     recommendation: stash, or Park commit\n\n (2) you have started working but realized what you are working on belongs\n     to a new topic.\n\n     recommendation: checkout -b\n\n (3) you have started working but realized what you are working on belongs\n     to an existing topic.\n\n     recommendation: checkout -m\n\nIn case (1), if the change is small, trivial or independent from what you\nare switching branches to work on, you can \"git checkout\" (if the change\nis about an unrelated thing, hopefully there won't be any overlap at the\nfile level) or \"git checkout -m\" (again, if the change is about an\nunrelated thing, the merge hopefully would be trivial) to switch branches,\nperform the unrelated change and commit only that unrelated change, and\n\"git checkout\" (or \"git checkout -m\") to come back to where you started.\nBut if you had to use \"-m\" when switching branches, that means the change\nyou need to commit in the switched branch may have to include some changes\nyou will do to that modified file, and you would need per-hunk commit with\n\"git add -i\" to exclude existing changes.  In such a case, stashing the\nlocal changes away before branch switching would be much easier workflow.\n\nIn case (2), the solution is always \"checkout -b\".  There is no other\nchoice.\n\nIn case (3), the solution is always \"checkout -m\".  Stashing, switching\nand then unstashing will give the same conflicts as \"checkout -m\" would\ngive you, and the change you were working on has to be done on that\nswitched to branch, so there is no escaping from conflict resolution,\nunless you are willing to redo your change on the breanch you switched to\nagain.\n"},{"id":"72567","messageId":"5929C66E-EC03-4C1A-BC7A-14823B97DD64@faithfulgeek.org","threadId":"12787","inReplyTo":"7vod98u1pr.fsf@gitster.siamese.dyndns.org","subject":"Re: Switching branches without committing changes","fromName":"Joe Fiorini","fromEmail":"joe@faithfulgeek.org","sentAt":"2008-03-21T04:58:37Z","receivedAt":"2008-03-21T04:58:37Z","isPatch":false,"sender":{"key":"joe@faithfulgeek.org","avatar":null},"body":"Thanks all for the great info!  The scenarios you describe, Junio,  \nmake perfect sense.  In fact, that's pretty much the way I think when  \nI'm coding and decided to branch or not to branch (that is the  \nquestion).  Along the lines of those scenarios (maybe this should be a  \nseparate post), are there any guidelines or best practices on when/if  \nto sync your branches with master (hope that's not a stupid question,  \nI'm still learning)?\n\n-Joe\n\nOn Mar 21, 2008, at 12:42 AM, Junio C Hamano wrote:\n\n> Jeff King <peff@peff.net> writes:\n>\n>> On Fri, Mar 21, 2008 at 12:06:47AM -0400, Shawn O. Pearce wrote:\n>>\n>>> Use `git checkout -m` to switch the branch anyway.  However, if\n>>> there is a merge conflict while you are trying to carry the changes\n>>> to the other branch you may be faced with a merge conflict you are\n>>> not prepared to resolve, or simply cannot resolve in a reasonable\n>>> period of time.\n>>\n>> Ah, for some reason I didn't think of '-m' in the advice I gave (I  \n>> guess\n>> I have just never used it). It is almost certainly simpler than  \n>> using a\n>> 'stash' at this point (but I do think stashing _beforehand_ still has\n>> advantages).\n>\n> The thing is, that -m is really to mollify people who are _too_  \n> accustomed\n> to CVS/SVN update behaviour.  Over there, \"scm update\" does not give  \n> you\n> any choice other than having to merge.\n>\n> With git, stashing or creating Park commits are very cheap operation  \n> and\n> unless you are reasonably sure that your local changes do not conflict\n> with the branch you are switching to, there is no strong reason to  \n> prefer\n> \"checkout -m\".\n>\n> Switching branches with dirty state can have three scenarios:\n>\n> (1) you are getting interrupted and your current local changes do not\n>     belong to what you are going to commit after switching (e.g. \"the\n>     boss says fix that right away\").\n>\n>     recommendation: stash, or Park commit\n>\n> (2) you have started working but realized what you are working on  \n> belongs\n>     to a new topic.\n>\n>     recommendation: checkout -b\n>\n> (3) you have started working but realized what you are working on  \n> belongs\n>     to an existing topic.\n>\n>     recommendation: checkout -m\n>\n> In case (1), if the change is small, trivial or independent from  \n> what you\n> are switching branches to work on, you can \"git checkout\" (if the  \n> change\n> is about an unrelated thing, hopefully there won't be any overlap at  \n> the\n> file level) or \"git checkout -m\" (again, if the change is about an\n> unrelated thing, the merge hopefully would be trivial) to switch  \n> branches,\n> perform the unrelated change and commit only that unrelated change,  \n> and\n> \"git checkout\" (or \"git checkout -m\") to come back to where you  \n> started.\n> But if you had to use \"-m\" when switching branches, that means the  \n> change\n> you need to commit in the switched branch may have to include some  \n> changes\n> you will do to that modified file, and you would need per-hunk  \n> commit with\n> \"git add -i\" to exclude existing changes.  In such a case, stashing  \n> the\n> local changes away before branch switching would be much easier  \n> workflow.\n>\n> In case (2), the solution is always \"checkout -b\".  There is no other\n> choice.\n>\n> In case (3), the solution is always \"checkout -m\".  Stashing,  \n> switching\n> and then unstashing will give the same conflicts as \"checkout -m\"  \n> would\n> give you, and the change you were working on has to be done on that\n> switched to branch, so there is no escaping from conflict resolution,\n> unless you are willing to redo your change on the breanch you  \n> switched to\n> again.\n>\n>\n>\n>\n"},{"id":"72717","messageId":"200803230100.m2N102oR025238@localhost.localdomain","threadId":"12787","inReplyTo":"7vod98u1pr.fsf@gitster.siamese.dyndns.org","subject":"Re: Switching branches without committing changes","fromName":"Xavier Maillard","fromEmail":"xma@gnu.org","sentAt":"2008-03-23T01:00:02Z","receivedAt":"2008-03-23T01:00:02Z","isPatch":false,"sender":{"key":"xma@gnu.org","avatar":null},"body":"\n   Jeff King <peff@peff.net> writes:\n\n   > On Fri, Mar 21, 2008 at 12:06:47AM -0400, Shawn O. Pearce wrote:\n   >\n   >> Use `git checkout -m` to switch the branch anyway.  However, if\n   >> there is a merge conflict while you are trying to carry the changes\n   >> to the other branch you may be faced with a merge conflict you are\n   >> not prepared to resolve, or simply cannot resolve in a reasonable\n   >> period of time.\n   >\n   > Ah, for some reason I didn't think of '-m' in the advice I gave (I guess\n   > I have just never used it). It is almost certainly simpler than using a\n   > 'stash' at this point (but I do think stashing _beforehand_ still has\n   > advantages).\n\n   The thing is, that -m is really to mollify people who are _too_ accustomed\n   to CVS/SVN update behaviour.  Over there, \"scm update\" does not give you\n   any choice other than having to merge.\n\nThis post is *yet* another valuable candidate to put onto the wiki.\n\n\tXavier\n-- \nhttp://www.gnu.org\nhttp://www.april.org\nhttp://www.lolica.org\n"},{"id":"72896","messageId":"8AD80272-53D2-4020-9F53-F4249DEEDF4B@faithfulgeek.org","threadId":"12787","inReplyTo":"200803230100.m2N102oR025238@localhost.localdomain","subject":"Re: Switching branches without committing changes","fromName":"Joe Fiorini","fromEmail":"joe@faithfulgeek.org","sentAt":"2008-03-24T14:46:06Z","receivedAt":"2008-03-24T14:46:06Z","isPatch":false,"sender":{"key":"joe@faithfulgeek.org","avatar":null},"body":"Can you send me a link to the official wiki?  If I have access to it,  \nI will see about updating it today.\n\n-Joe\n\nOn Mar 22, 2008, at 9:00 PM, Xavier Maillard wrote:\n\n>\n>   Jeff King <peff@peff.net> writes:\n>\n>> On Fri, Mar 21, 2008 at 12:06:47AM -0400, Shawn O. Pearce wrote:\n>>\n>>> Use `git checkout -m` to switch the branch anyway.  However, if\n>>> there is a merge conflict while you are trying to carry the changes\n>>> to the other branch you may be faced with a merge conflict you are\n>>> not prepared to resolve, or simply cannot resolve in a reasonable\n>>> period of time.\n>>\n>> Ah, for some reason I didn't think of '-m' in the advice I gave (I  \n>> guess\n>> I have just never used it). It is almost certainly simpler than  \n>> using a\n>> 'stash' at this point (but I do think stashing _beforehand_ still has\n>> advantages).\n>\n>   The thing is, that -m is really to mollify people who are _too_  \n> accustomed\n>   to CVS/SVN update behaviour.  Over there, \"scm update\" does not  \n> give you\n>   any choice other than having to merge.\n>\n> This post is *yet* another valuable candidate to put onto the wiki.\n>\n> \tXavier\n> -- \n> http://www.gnu.org\n> http://www.april.org\n> http://www.lolica.org\n"},{"id":"72933","messageId":"20080324190710.GA14002@coredump.intra.peff.net","threadId":"12787","inReplyTo":"8AD80272-53D2-4020-9F53-F4249DEEDF4B@faithfulgeek.org","subject":"Re: Switching branches without committing changes","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-03-24T19:07:11Z","receivedAt":"2008-03-24T19:07:11Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Mar 24, 2008 at 10:46:06AM -0400, Joe Fiorini wrote:\n\n> Can you send me a link to the official wiki?  If I have access to it, I \n> will see about updating it today.\n\nhttp://git.or.cz/gitwiki\n\n-Peff\n"}]}