{"thread":{"id":"41053","subject":"\"git stash pop\" is doing an unwanted \"git add\" when there are conflicts.","startedAt":"2015-12-21T14:29:54Z","lastAt":"2015-12-30T07:13:20Z","messageCount":10,"participants":["Alan Mackenzie","Dennis Kaarsemaker","Jeff King","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"274803","messageId":"20151221142953.GA12764@acm.fritz.box","threadId":"41053","inReplyTo":null,"subject":"\"git stash pop\" is doing an unwanted \"git add\" when there are conflicts.","fromName":"Alan Mackenzie","fromEmail":"acm@muc.de","sentAt":"2015-12-21T14:29:54Z","receivedAt":"2015-12-21T14:29:54Z","isPatch":false,"sender":{"key":"acm@muc.de","avatar":null},"body":"Hello, git project.\n\nLast night, whilst clearing out a stale \"stash stack\", I did \"git stash\npop\".  There were conflicts in two files.\n\nHowever, all the popped files became staged.  This doesn't normally happen.\nIt was intensely irritating, and required me to do \"git reset HEAD\" on\neach of the files, none of which I wanted to commit.\n\nI searched the git-stash man page for this scenario, but found nothing\nabout it.\n\nSurely staging all the files is a bug?\n\n-- \nAlan Mackenzie (Nuremberg, Germany).\n"},{"id":"274827","messageId":"n59nnp$t0m$2@ger.gmane.org","threadId":"41053","inReplyTo":"20151221142953.GA12764@acm.fritz.box","subject":"Re: \"git stash pop\" is doing an unwanted \"git add\" when there are conflicts.","fromName":"Alan Mackenzie","fromEmail":"acm@muc.de","sentAt":"2015-12-21T20:34:01Z","receivedAt":"2015-12-21T20:34:01Z","isPatch":false,"sender":{"key":"acm@muc.de","avatar":null},"body":"Alan Mackenzie <acm@muc.de> wrote: on Mon, 21 Dec 2015 14:29:54\n> Hello, git project.\n\n> Last night, whilst clearing out a stale \"stash stack\", I did \"git stash\n> pop\".  There were conflicts in two files.\n\n> However, all the popped files became staged.  This doesn't normally happen.\n> It was intensely irritating, and required me to do \"git reset HEAD\" on\n> each of the files, none of which I wanted to commit.\n\n> I searched the git-stash man page for this scenario, but found nothing\n> about it.\n\n> Surely staging all the files is a bug?\n\nSorry, forgot to mention I'm using git 2.4.10 on GNU/Linux.\n\n-- \nAlan Mackenzie (Nuremberg, Germany).\n"},{"id":"274843","messageId":"1450772258.7937.9.camel@kaarsemaker.net","threadId":"41053","inReplyTo":"20151221142953.GA12764@acm.fritz.box","subject":"Re: \"git stash pop\" is doing an unwanted \"git add\" when there are conflicts.","fromName":"Dennis Kaarsemaker","fromEmail":"dennis@kaarsemaker.net","sentAt":"2015-12-22T08:17:38Z","receivedAt":"2015-12-22T08:17:38Z","isPatch":false,"sender":{"key":"dennis@kaarsemaker.net","avatar":"https://avatars.githubusercontent.com/u/200649?v=4"},"body":"On ma, 2015-12-21 at 14:29 +0000, Alan Mackenzie wrote:\n> Hello, git project.\n> \n> Last night, whilst clearing out a stale \"stash stack\", I did \"git stash\n> pop\".  There were conflicts in two files.\n> \n> However, all the popped files became staged.  This doesn't normally happen.\n> It was intensely irritating, and required me to do \"git reset HEAD\" on\n> each of the files, none of which I wanted to commit.\n> \n> I searched the git-stash man page for this scenario, but found nothing\n> about it.\n> \n> Surely staging all the files is a bug?\n\nThat depends. A stash is two commits: one for all changes that were in\nthe index when you ran 'git stash save' and one for all changes not yet\nin the index. When you pop the stash, these then get restored as staged\nresp. unstaged changes. So if your changes are now all staged, I'd\nwager that they were staged when you ran git stash save.\n\n-- \nDennis Kaarsemaker\nwww.kaarsemaker.net\n"},{"id":"274848","messageId":"20151222093032.GA5173@sigill.intra.peff.net","threadId":"41053","inReplyTo":"1450772258.7937.9.camel@kaarsemaker.net","subject":"Re: \"git stash pop\" is doing an unwanted \"git add\" when there are conflicts.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-12-22T09:30:33Z","receivedAt":"2015-12-22T09:30:33Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Dec 22, 2015 at 09:17:38AM +0100, Dennis Kaarsemaker wrote:\n\n> On ma, 2015-12-21 at 14:29 +0000, Alan Mackenzie wrote:\n> > Hello, git project.\n> > \n> > Last night, whilst clearing out a stale \"stash stack\", I did \"git stash\n> > pop\".  There were conflicts in two files.\n> > \n> > However, all the popped files became staged.  This doesn't normally happen.\n> > It was intensely irritating, and required me to do \"git reset HEAD\" on\n> > each of the files, none of which I wanted to commit.\n> > \n> > I searched the git-stash man page for this scenario, but found nothing\n> > about it.\n> > \n> > Surely staging all the files is a bug?\n> \n> That depends. A stash is two commits: one for all changes that were in\n> the index when you ran 'git stash save' and one for all changes not yet\n> in the index. When you pop the stash, these then get restored as staged\n> resp. unstaged changes. So if your changes are now all staged, I'd\n> wager that they were staged when you ran git stash save.\n\nNo, I think there's something else going on. Try this:\n  \n    git init repo &&\n    cd repo &&\n    \n    echo base >one &&\n    echo base >two &&\n    git add . &&\n    git commit -m base &&\n    \n    echo stash >one &&\n    echo stash >two &&\n    git stash &&\n    \n    echo \"==> No conflicts, nothing staged\"\n    git stash apply &&\n    \n    git reset --hard &&\n    echo changes >two &&\n    git commit -am changes &&\n    \n    echo \"==> Conflict stages non-conflicting file 'one'\"\n    ! git stash apply &&\n    git status\n\nIt seems to be a side effect of merge-recursive to stage the results,\nand in the no-conflict path we explicitly reset the index. For the\nconflicting case, it's trickier, because we would want to retain the\nunmerged entries.\n\nSo I agree it's kind of weird, but the conflicting case is inherently\ngoing to touch the index, and you'd generally have to `git add` to mark\nthe resolutions (but if you really want to just touch the working tree,\nyou'd need to `git reset`).\n\n-Peff\n"},{"id":"274983","messageId":"20151224092038.GA2397@acm.fritz.box","threadId":"41053","inReplyTo":"20151222093032.GA5173@sigill.intra.peff.net","subject":"Re: \"git stash pop\" is doing an unwanted \"git add\" when there are conflicts.","fromName":"Alan Mackenzie","fromEmail":"acm@muc.de","sentAt":"2015-12-24T09:20:38Z","receivedAt":"2015-12-24T09:20:38Z","isPatch":false,"sender":{"key":"acm@muc.de","avatar":null},"body":"Hello, Jeff.\n\nOn Tue, Dec 22, 2015 at 04:30:33AM -0500, Jeff King wrote:\n> On Tue, Dec 22, 2015 at 09:17:38AM +0100, Dennis Kaarsemaker wrote:\n\n> > On ma, 2015-12-21 at 14:29 +0000, Alan Mackenzie wrote:\n> > > Hello, git project.\n\n> > > Last night, whilst clearing out a stale \"stash stack\", I did \"git stash\n> > > pop\".  There were conflicts in two files.\n\n> > > However, all the popped files became staged.  This doesn't normally happen.\n> > > It was intensely irritating, and required me to do \"git reset HEAD\" on\n> > > each of the files, none of which I wanted to commit.\n\n> > > I searched the git-stash man page for this scenario, but found nothing\n> > > about it.\n\n> > > Surely staging all the files is a bug?\n\n> > That depends. A stash is two commits: one for all changes that were in\n> > the index when you ran 'git stash save' and one for all changes not yet\n> > in the index. When you pop the stash, these then get restored as staged\n> > resp. unstaged changes. So if your changes are now all staged, I'd\n> > wager that they were staged when you ran git stash save.\n\n> No, I think there's something else going on. Try this:\n  \n>     git init repo &&\n>     cd repo &&\n    \n>     echo base >one &&\n>     echo base >two &&\n>     git add . &&\n>     git commit -m base &&\n    \n>     echo stash >one &&\n>     echo stash >two &&\n>     git stash &&\n    \n>     echo \"==> No conflicts, nothing staged\"\n>     git stash apply &&\n    \n>     git reset --hard &&\n>     echo changes >two &&\n>     git commit -am changes &&\n    \n>     echo \"==> Conflict stages non-conflicting file 'one'\"\n>     ! git stash apply &&\n>     git status\n\nThanks for creating a reproducible test case for me!\n\n> It seems to be a side effect of merge-recursive to stage the results,\n> and in the no-conflict path we explicitly reset the index. For the\n> conflicting case, it's trickier, because we would want to retain the\n> unmerged entries.\n\n> So I agree it's kind of weird, but the conflicting case is inherently\n> going to touch the index, and you'd generally have to `git add` to mark\n> the resolutions (but if you really want to just touch the working tree,\n> you'd need to `git reset`).\n\n>From the point of view of a user, this is suboptimal.  git stash is an\nabstraction: the preservation of uncomitted changes for later.  Staging\npreviously unstaged changes with git stash pop severely damages this\nabstraction.\n\nAre there any prospects of this getting fixed?\n\n> -Peff\n\n-- \nAlan Mackenzie (Nuremberg, Germany).\n"},{"id":"275109","messageId":"20151229075329.GA9254@sigill.intra.peff.net","threadId":"41053","inReplyTo":"20151224092038.GA2397@acm.fritz.box","subject":"Re: \"git stash pop\" is doing an unwanted \"git add\" when there are conflicts.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-12-29T07:53:30Z","receivedAt":"2015-12-29T07:53:30Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Dec 24, 2015 at 09:20:38AM +0000, Alan Mackenzie wrote:\n\n> > It seems to be a side effect of merge-recursive to stage the results,\n> > and in the no-conflict path we explicitly reset the index. For the\n> > conflicting case, it's trickier, because we would want to retain the\n> > unmerged entries.\n> \n> > So I agree it's kind of weird, but the conflicting case is inherently\n> > going to touch the index, and you'd generally have to `git add` to mark\n> > the resolutions (but if you really want to just touch the working tree,\n> > you'd need to `git reset`).\n> \n> From the point of view of a user, this is suboptimal.  git stash is an\n> abstraction: the preservation of uncomitted changes for later.  Staging\n> previously unstaged changes with git stash pop severely damages this\n> abstraction.\n\nYeah, I think I agree. But keep in mind that we have to mention the\nconflicts _somewhere_, so we're going to touch the index regardless (and\nthe user is going to have to erase the conflicts in the index\neventually, either with `git add` or `git reset`).\n\n> Are there any prospects of this getting fixed?\n\nSomebody needs to write a patch. I am not 100% convinced that it\n_should_ be fixed, but I am leaning that way. But I am not planning to\nwork on it myself anytime soon. The best way to get more discussion\ngoing is to post a patch. :)\n\n-Peff\n"},{"id":"275146","messageId":"xmqq37ulhya3.fsf@gitster.mtv.corp.google.com","threadId":"41053","inReplyTo":"20151229075329.GA9254@sigill.intra.peff.net","subject":"Re: \"git stash pop\" is doing an unwanted \"git add\" when there are conflicts.","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-12-29T19:04:20Z","receivedAt":"2015-12-29T19:04:20Z","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> Yeah, I think I agree. But keep in mind that we have to mention the\n> conflicts _somewhere_, so we're going to touch the index regardless (and\n> the user is going to have to erase the conflicts in the index\n> eventually, either with `git add` or `git reset`).\n\nI do not think there is much we can do at this point in time (but\nnotice that I did say \"much\", and didn't say \"anything\").\n\nThe way we replay any potentially conflicting change and present the\nresult to the end user in Git is uniformly to add the cleanly\napplied parts to the index while leaving the conflicted ones as\nunmerged index entries, but \"git stash apply/pop\" does not follow\nthis pattern.  I think this is partly because the command is also\nused to \"stash away\" a work-in-progress changes to the index, and\navoiding to touch the index with the changes in the working tree\nwould more closely match the behaviour of the command when there is\nno conflict.\n\nI notice that I said the same thing long time ago, i.e. in the\ninitial round of review:\n\n  http://article.gmane.org/gmane.comp.version-control.git/50749\n\n| However, I think it is a bit counterintuitive to update the\n| working tree change to the index if the merge did not conflict.\n| It might be better to run an equivalent of \"git reset\", so that\n| after \"git save restore\", the user can say \"git diff\" (not \"git\n| diff HEAD\") to view the local changes.  Perhaps...\n\nIn the above, I suggested to \"git reset\" when there is no conflict.\nI think this line of thinking can be followed even further to\nselectively reset the paths that were cleanly merged (which is added\nby the call to merge-recursive), leaving _only_ the conflicted paths.\n\nWould that give us a better outcome?  I dunno.\n\n>> Are there any prospects of this getting fixed?\n>\n> Somebody needs to write a patch. I am not 100% convinced that it\n> _should_ be fixed, but I am leaning that way. But I am not planning to\n> work on it myself anytime soon. The best way to get more discussion\n> going is to post a patch. :)\n"},{"id":"275150","messageId":"20151229212038.GD1884@acm.fritz.box","threadId":"41053","inReplyTo":"20151229075329.GA9254@sigill.intra.peff.net","subject":"Re: \"git stash pop\" is doing an unwanted \"git add\" when there are conflicts.","fromName":"Alan Mackenzie","fromEmail":"acm@muc.de","sentAt":"2015-12-29T21:20:38Z","receivedAt":"2015-12-29T21:20:38Z","isPatch":false,"sender":{"key":"acm@muc.de","avatar":null},"body":"Hello, Jeff.\n\nOn Tue, Dec 29, 2015 at 02:53:30AM -0500, Jeff King wrote:\n> On Thu, Dec 24, 2015 at 09:20:38AM +0000, Alan Mackenzie wrote:\n\n> > > It seems to be a side effect of merge-recursive to stage the results,\n> > > and in the no-conflict path we explicitly reset the index. For the\n> > > conflicting case, it's trickier, because we would want to retain the\n> > > unmerged entries.\n\n> > > So I agree it's kind of weird, but the conflicting case is inherently\n> > > going to touch the index, and you'd generally have to `git add` to mark\n> > > the resolutions (but if you really want to just touch the working tree,\n> > > you'd need to `git reset`).\n\n> > From the point of view of a user, this is suboptimal.  git stash is an\n> > abstraction: the preservation of uncomitted changes for later.  Staging\n> > previously unstaged changes with git stash pop severely damages this\n> > abstraction.\n\n> Yeah, I think I agree. But keep in mind that we have to mention the\n> conflicts _somewhere_, so we're going to touch the index regardless (and\n> the user is going to have to erase the conflicts in the index\n> eventually, either with `git add` or `git reset`).\n\nWhen the stash consists entirely of changes in the working directory,\nand \"git stash pop\" has conflicts, why can't these conflicts simply be\nmarked by \"<<<<<<<<\" (etc.) in the working directory, leaving the index\nunchanged?  The index is left unchanged when there are no conlicts.\n\n> > Are there any prospects of this getting fixed?\n\n> Somebody needs to write a patch. I am not 100% convinced that it\n> _should_ be fixed, but I am leaning that way. But I am not planning to\n> work on it myself anytime soon. The best way to get more discussion\n> going is to post a patch. :)\n\nHmm.  I would very much prefer to remain just a user of git.\n\n> -Peff\n\n-- \nAlan Mackenzie (Nuremberg, Germany).\n"},{"id":"275168","messageId":"20151230070238.GA29896@sigill.intra.peff.net","threadId":"41053","inReplyTo":"20151229212038.GD1884@acm.fritz.box","subject":"Re: \"git stash pop\" is doing an unwanted \"git add\" when there are conflicts.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-12-30T07:02:38Z","receivedAt":"2015-12-30T07:02:38Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Dec 29, 2015 at 09:20:38PM +0000, Alan Mackenzie wrote:\n\n> > Yeah, I think I agree. But keep in mind that we have to mention the\n> > conflicts _somewhere_, so we're going to touch the index regardless (and\n> > the user is going to have to erase the conflicts in the index\n> > eventually, either with `git add` or `git reset`).\n> \n> When the stash consists entirely of changes in the working directory,\n> and \"git stash pop\" has conflicts, why can't these conflicts simply be\n> marked by \"<<<<<<<<\" (etc.) in the working directory, leaving the index\n> unchanged?  The index is left unchanged when there are no conlicts.\n\nI don't think that's a good idea. Git always marks conflicts in the\nindex for other operations. Besides being inconsistent with the rest of\ngit, it drops useful information that other tools can use. For example,\none cannot \"git checkout --conflict=diff3\" afterwards, or use \"git\nmergetool\" to kick off a third-party merge tool.\n\nNot to mention that the information is lost to the user themselves. If\nwe touched 10 files and 2 had conflicts, there is now no way for the\nuser to ask \"where were the conflicts?\". They can either find the stash\noutput in their terminal scrollback, or grep for things that look like\nconflict markers.\n\n-Peff\n"},{"id":"275169","messageId":"20151230071319.GC26964@sigill.intra.peff.net","threadId":"41053","inReplyTo":"xmqq37ulhya3.fsf@gitster.mtv.corp.google.com","subject":"Re: \"git stash pop\" is doing an unwanted \"git add\" when there are conflicts.","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-12-30T07:13:20Z","receivedAt":"2015-12-30T07:13:20Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Dec 29, 2015 at 11:04:20AM -0800, Junio C Hamano wrote:\n\n> [...]\n> In the above, I suggested to \"git reset\" when there is no conflict.\n> I think this line of thinking can be followed even further to\n> selectively reset the paths that were cleanly merged (which is added\n> by the call to merge-recursive), leaving _only_ the conflicted paths.\n> \n> Would that give us a better outcome?  I dunno.\n\nYes, I think that is the only sensible change to make. The only other\noption (besides leaving it as-is) would be to unstage _everything_\nleaving conflict-marker cruft in the working tree, but no conflicts in\nthe index. I think that's a mistake, but I won't repeat the arguments I\nleft elsewhere in the thread.\n\nSo it's probably something like:\n\n  git ls-files -t |\n  grep -v ^M |\n  cut -d ' ' -f2- |\n  xargs git reset --\n\n(modulo some quoting robustness improvements). But I guess we'd want to\npreserve any modifications that were originally in the index. So maybe\nthe intersection of the files above and the output of \"git diff-tree\n--name-only\" on the stash commit.\n\nThere are probably some corner cases to look at (e.g., with \"--index\").\n\nAs I said, I'm not planning to work on it anytime soon, but the above\nmay give some clues to somebody who wants to pursue it.\n\n-Peff\n"}]}