{"thread":{"id":"31707","subject":"Unstaging during a merge conflict","startedAt":"2012-10-02T01:13:21Z","lastAt":"2012-10-03T22:01:22Z","messageCount":3,"participants":["Matt McClellan","Junio C Hamano","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"200306","messageId":"CAHUDv6qM37nua2uB6TDOmf1a5L_TUFz=0q=v5W=9MrpEmWoShg@mail.gmail.com","threadId":"31707","inReplyTo":null,"subject":"Unstaging during a merge conflict","fromName":"Matt McClellan","fromEmail":"mcclellan.mj@gmail.com","sentAt":"2012-10-02T01:13:21Z","receivedAt":"2012-10-02T01:13:21Z","isPatch":false,"sender":{"key":"mcclellan.mj@gmail.com","avatar":null},"body":"We had an issue at our organization where changes were reverted when a\nuser was merging his local repo with the remote repo changes.  The\nmerge conflicted and he unstaged all the changes that were not a\nconflict, he then resolved the conflict and added just the conflicted\nfile and committed.  The end result was that he reverted every change\nfrom his last pull of the remote to his merge point.  The problem I'm\nhaving how hard it is to see this problem as both git show and git log\non the merge commit do not show any reverted files.  It was found by\ndiffing his commit to each of the parents and seeing the opposite of\nwhat we expected in the patch output.\n\nAnybody have ideas how we can prevent these mistakes?  While we are\ngoing to do more training, a hard stop that wouldn't even let these\nmake it to remote would be preferred.\n\nI've done this using git add --interactive then reverting a files\nchanges, though the actual crime was done using egit staging tool.  It\nseems the command line won't let you unstage changes but gui tools and\ninteractive tools seem to allow it.\n"},{"id":"200347","messageId":"7v4nmcaitf.fsf@alter.siamese.dyndns.org","threadId":"31707","inReplyTo":"CAHUDv6qM37nua2uB6TDOmf1a5L_TUFz=0q=v5W=9MrpEmWoShg@mail.gmail.com","subject":"Re: Unstaging during a merge conflict","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-10-02T17:24:12Z","receivedAt":"2012-10-02T17:24:12Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matt McClellan <mcclellan.mj@gmail.com> writes:\n\n> I've done this using git add --interactive then reverting a files\n> changes, though the actual crime was done using egit staging tool.  It\n> seems the command line won't let you unstage changes but gui tools and\n> interactive tools seem to allow it.\n\nI think you could do \"git reset [--mixed]\" from the command line to\ninduce the same mistake.  It may be that it is much less likely for\npeople to do this from the command line because the command name is\n\"reset\" that is spelled in red ;-) than some GUI programs without a\ncareful UI to mark potentially dangerous operations as such, like we\ndo in the CLI.\n"},{"id":"200471","messageId":"20121003220122.GE4484@sigill.intra.peff.net","threadId":"31707","inReplyTo":"CAHUDv6qM37nua2uB6TDOmf1a5L_TUFz=0q=v5W=9MrpEmWoShg@mail.gmail.com","subject":"Re: Unstaging during a merge conflict","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-10-03T22:01:22Z","receivedAt":"2012-10-03T22:01:22Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Oct 01, 2012 at 08:13:21PM -0500, Matt McClellan wrote:\n\n> We had an issue at our organization where changes were reverted when a\n> user was merging his local repo with the remote repo changes.  The\n> merge conflicted and he unstaged all the changes that were not a\n> conflict, he then resolved the conflict and added just the conflicted\n> file and committed.  The end result was that he reverted every change\n> from his last pull of the remote to his merge point.  The problem I'm\n> having how hard it is to see this problem as both git show and git log\n> on the merge commit do not show any reverted files.  It was found by\n> diffing his commit to each of the parents and seeing the opposite of\n> what we expected in the patch output.\n> \n> Anybody have ideas how we can prevent these mistakes?  While we are\n> going to do more training, a hard stop that wouldn't even let these\n> make it to remote would be preferred.\n\nThe problem is that from the remote's perspective, it is too late. These\nunstaged paths look exactly as if they were simply resolved in favor of\nthe \"ours\" side of the merge. The remote does not even see that they had\nconflicts, but only that the path from one side was taken over the\nother.  If it wanted to be careful, it could recreate the merge and\nnotice that they did not, but even that will lead to some errors. For\nexample, resolving another conflict may result in a situation where a\nchange in another file becomes unwanted and is dropped.\n\nSo I think any kind of receive hook to prevent these mistakes from being\npropagated is going to run afoul of legitimate cases. You'd do much\nbetter to work on the UI of the resolution workflow to prevent the\nmistake from happening in the first place.\n\n> I've done this using git add --interactive then reverting a files\n> changes, though the actual crime was done using egit staging tool.  It\n> seems the command line won't let you unstage changes but gui tools and\n> interactive tools seem to allow it.\n\nYou can do \"git checkout HEAD <path>\" from the command-line. But I would\nhope that the results of doing so are sufficiently obvious. Doing\nsomething like \"git reset\" is much more subtle, but it is reasonably\nwell-known as a dangerous command, and I hope we are not encouraging it\nto new people.\n\nDoing a full revert of a path during merge resolution is probably fishy.\nIt might make sense for \"git add -i\" to warn about it (I haven't used\negit's staging tool, but presumably the same thing would apply).\n\nAnother place to catch your issue (assuming that an unstaging tool was\nused, leaving the modified contents in the working tree) would be to\nnotice unstaged changes in the working tree when committing a merge.\nThe problem with forbidding it is that it is also a legitimate thing to\ndo (e.g., because you carry some local modification to a file that you\ndo not want to commit), so it is not necessarily indicative of an error.\nBut in theory you would see a giant list of unstaged changes in the\ncommit message template. I wonder if that is less obvious when\ncommitting via egit.\n\n-Peff\n"}]}