{"thread":{"id":"29515","subject":"How to find and analyze bad merges?","startedAt":"2012-02-02T08:10:06Z","lastAt":"2012-02-02T20:09:00Z","messageCount":11,"participants":["norbert.nemec","Junio C Hamano","Norbert Nemec","David Barr","Jonathan Nieder","Neal Groothuis"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"183547","messageId":"jgdgcv$h8n$1@dough.gmane.org","threadId":"29515","inReplyTo":null,"subject":"How to find and analyze bad merges?","fromName":"norbert.nemec","fromEmail":"norbert.nemec@native-instruments.de","sentAt":"2012-02-02T08:10:06Z","receivedAt":"2012-02-02T08:10:06Z","isPatch":false,"sender":{"key":"norbert.nemec@native-instruments.de","avatar":null},"body":"Hi there,\n\na colleague of mine happened to produce a bad merge by unintenionally \npicking the version of the remote branch (\"R\") for all conflicting \nfiles. Effectively, he eliminated a whole bunch of bugfixes that were \nalready on his local branch (\"L\").\n\nObviously this was a mistake on his side, but hey: everyone makes \nmistakes. The real problem is to find this problem afterwards, possibly \nweeks later, when you suddenly realize that a bug that you had fixed \nsuddenly reappears.\n\nA \"git log\" on the whole repository shows both branches R and L.\nA \"git show\" on the bugfix commit shows the bugfix as you expect it.\n\nBUT:\nA \"git log\" on the file itself shows neither the problematic merge nor \nthe bugfix commit. Git considers the merge of this file trivial because \nthe content is identical to that of parent R. Therefore, whatever \nhappened on branch L is not considered relevant history of the file.\n\nFURTHERMORE:\nA \"git show\" of the merge itself does not show the conflicting file \neither. Obviously, \"git show\" on a merge decides which files are \nrelevant not based on conflicts but based on resolutions.\n\nTo sort out what happened, you first need to have a suspicion and then \ndig fairly deep in the manuals to set the correct options to show what \nhappened.\n\nI think, both \"git log\" and \"git show\" should by default be a bit more \nconservative in hiding \"insignificant\" merges:\n* In \"git log\" a branch should only be hidden if it never touched the file.\n* In \"git show\" a merge should display all files that did have a \nconflict independent of the resolution. (I am open to discuss whether \nauto-resolvable conflicts should be displayed by default. Non-trivial \nconflicts definitely should)\n\nGreetings,\nNorbert\n"},{"id":"183550","messageId":"7vd39xy7it.fsf@alter.siamese.dyndns.org","threadId":"29515","inReplyTo":"jgdgcv$h8n$1@dough.gmane.org","subject":"Re: How to find and analyze bad merges?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-02-02T08:16:42Z","receivedAt":"2012-02-02T08:16:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"norbert.nemec\" <norbert.nemec@native-instruments.de> writes:\n\n> a colleague of mine happened to produce a bad merge by unintenionally\n> picking the version of the remote branch (\"R\") for all conflicting\n> files. Effectively, he eliminated a whole bunch of bugfixes that were\n> already on his local branch (\"L\").\n>\n> Obviously this was a mistake on his side, but hey: everyone makes\n> mistakes. The real problem is to find this problem afterwards,\n> possibly weeks later, when you suddenly realize that a bug that you\n> had fixed suddenly reappears.\n\nBisect?\n"},{"id":"183564","messageId":"jgdjd1$5mn$1@dough.gmane.org","threadId":"29515","inReplyTo":"7vd39xy7it.fsf@alter.siamese.dyndns.org","subject":"Re: How to find and analyze bad merges?","fromName":"norbert.nemec","fromEmail":"norbert.nemec@native-instruments.de","sentAt":"2012-02-02T09:01:18Z","receivedAt":"2012-02-02T09:01:18Z","isPatch":false,"sender":{"key":"norbert.nemec@native-instruments.de","avatar":null},"body":"Am 02.02.12 09:16, schrieb Junio C Hamano:\n> \"norbert.nemec\"<norbert.nemec@native-instruments.de>  writes:\n>\n>> a colleague of mine happened to produce a bad merge by unintenionally\n>> picking the version of the remote branch (\"R\") for all conflicting\n>> files. Effectively, he eliminated a whole bunch of bugfixes that were\n>> already on his local branch (\"L\").\n>>\n>> Obviously this was a mistake on his side, but hey: everyone makes\n>> mistakes. The real problem is to find this problem afterwards,\n>> possibly weeks later, when you suddenly realize that a bug that you\n>> had fixed suddenly reappears.\n>\n> Bisect?\n\nThis is not the point: My colleague knew exactly which commit contained \nthe bugfix. The trouble was finding out why this bugfix disappeared even \nthough everything indicated that it was cleanly merged into the current \nbranch.\n"},{"id":"183572","messageId":"jgdn5j$v4g$1@dough.gmane.org","threadId":"29515","inReplyTo":"jgdgcv$h8n$1@dough.gmane.org","subject":"Re: How to find and analyze bad merges?","fromName":"norbert.nemec","fromEmail":"norbert.nemec@native-instruments.de","sentAt":"2012-02-02T10:05:34Z","receivedAt":"2012-02-02T10:05:34Z","isPatch":false,"sender":{"key":"norbert.nemec@native-instruments.de","avatar":null},"body":"Thinking about a possible solution:\n\nIs there a way to re-do a merge-commit and diff the result against the \nrecorded merge without touching the working tree? This would be the \nkiller-feature to analyze a recorded merge-commit.\n\n\n\nAm 02.02.12 09:10, schrieb norbert.nemec:\n> Hi there,\n>\n> a colleague of mine happened to produce a bad merge by unintenionally\n> picking the version of the remote branch (\"R\") for all conflicting\n> files. Effectively, he eliminated a whole bunch of bugfixes that were\n> already on his local branch (\"L\").\n>\n> Obviously this was a mistake on his side, but hey: everyone makes\n> mistakes. The real problem is to find this problem afterwards, possibly\n> weeks later, when you suddenly realize that a bug that you had fixed\n> suddenly reappears.\n>\n> A \"git log\" on the whole repository shows both branches R and L.\n> A \"git show\" on the bugfix commit shows the bugfix as you expect it.\n>\n> BUT:\n> A \"git log\" on the file itself shows neither the problematic merge nor\n> the bugfix commit. Git considers the merge of this file trivial because\n> the content is identical to that of parent R. Therefore, whatever\n> happened on branch L is not considered relevant history of the file.\n>\n> FURTHERMORE:\n> A \"git show\" of the merge itself does not show the conflicting file\n> either. Obviously, \"git show\" on a merge decides which files are\n> relevant not based on conflicts but based on resolutions.\n>\n> To sort out what happened, you first need to have a suspicion and then\n> dig fairly deep in the manuals to set the correct options to show what\n> happened.\n>\n> I think, both \"git log\" and \"git show\" should by default be a bit more\n> conservative in hiding \"insignificant\" merges:\n> * In \"git log\" a branch should only be hidden if it never touched the file.\n> * In \"git show\" a merge should display all files that did have a\n> conflict independent of the resolution. (I am open to discuss whether\n> auto-resolvable conflicts should be displayed by default. Non-trivial\n> conflicts definitely should)\n>\n> Greetings,\n> Norbert\n>\n"},{"id":"183588","messageId":"4F2A70DA.6020107@native-instruments.de","threadId":"29515","inReplyTo":"87haz97c2k.fsf@thomas.inf.ethz.ch","subject":"Re: How to find and analyze bad merges?","fromName":"Norbert Nemec","fromEmail":"norbert.nemec@native-instruments.de","sentAt":"2012-02-02T11:17:46Z","receivedAt":"2012-02-02T11:17:46Z","isPatch":false,"sender":{"key":"norbert.nemec@native-instruments.de","avatar":null},"body":"To be yet more precise:\n\nMy complaint is that you need this kind of sledge-hammer solutions to \nanalyze the situation. I, as an semi-expert with git did manage to find \nthe problem without even having to resort to bisect or manually redoing \nthe merge. My complaint is about the perspective of the \nmedium-experienced user who is completely puzzled by the fact that a\n\"git log <filename>\" silently skips the critical merge commit.\n\n\n\n\nAm 02.02.12 11:40, schrieb Thomas Rast:\n> \"norbert.nemec\"<norbert.nemec@native-instruments.de>  writes:\n>\n>> Thinking about a possible solution:\n>>\n>> Is there a way to re-do a merge-commit and diff the result against the\n>> recorded merge without touching the working tree? This would be the\n>> killer-feature to analyze a recorded merge-commit.\n>\n>    git checkout M^\n>    git merge M^2\n>    git diff M HEAD\n>\n> You'd have to resolve conflicts though.  If you want to skip that, I\n> think you could still see some information if you said\n>\n>    git reset\n>    git diff M\n>\n> to see the differences between the (unmerged, with conflict hunks) state\n> in the worktree and M.\n>\n> (Remember to re-attach your HEAD after playing around like this.)\n>\n>> Am 02.02.12 09:16, schrieb Junio C Hamano:\n>>>\n>>> Bisect?\n>>\n>> This is not the point: My colleague knew exactly which commit\n>> contained the bugfix. The trouble was finding out why this bugfix\n>> disappeared even though everything indicated that it was cleanly\n>> merged into the current branch.\n>\n> But that makes it a prime candidate for bisect: you know the good commit\n> (the original bugfix), and you know that the newest version is bad.\n> Bonus points if you have an automated test for it, in which case bisect\n> can nail the offender while you get coffee.\n>\n> Or am I missing something?\n>\n\n-- \nDr. Norbert Nemec\nTeamleader Software Development\n\nTel +49-30-611035-1882\nnorbert.nemec@native-instruments.de\n\nKOMPLETE 8 ULTIMATE - the premium NI producer collection\n=>  http://www.native-instruments.com/komplete8\n\nTRAKTOR KONTROL S2 - the professional 2.1 DJ system\n=>  http://www.native-instruments.com/s2\n\n->>>>>> NATIVE INSTRUMENTS - The Future of Sound <<<<<<-\n\nRegistergericht: Amtsgericht Charlottenburg\nRegisternummer: HRB 72458\nUST.-ID.-Nr. DE 20 374 7747\n\nGeschäftsführung: Daniel Haver (CEO), Mate Galic\n"},{"id":"183591","messageId":"CAFfmPPMc1V97OPHyrZp+p4YUek1c6fCncyj0s1YU9xjxQBCsDA@mail.gmail.com","threadId":"29515","inReplyTo":"4F2A70DA.6020107@native-instruments.de","subject":"Re: How to find and analyze bad merges?","fromName":"David Barr","fromEmail":"davidbarr@google.com","sentAt":"2012-02-02T11:41:16Z","receivedAt":"2012-02-02T11:41:16Z","isPatch":false,"sender":{"key":"davidbarr@google.com","avatar":"https://avatars.githubusercontent.com/u/220594?v=4"},"body":"On Thu, Feb 2, 2012 at 10:17 PM, Norbert Nemec\n<norbert.nemec@native-instruments.de> wrote:\n> To be yet more precise:\n>\n> My complaint is that you need this kind of sledge-hammer solutions to\n> analyze the situation. I, as an semi-expert with git did manage to find the\n> problem without even having to resort to bisect or manually redoing the\n> merge. My complaint is about the perspective of the medium-experienced user\n> who is completely puzzled by the fact that a\n> \"git log <filename>\" silently skips the critical merge commit.\n\nDo the -c --cc or -m flags for git log help in this case?\nThey alter the way merge diffs are presented, as described under Diff Formatting\nin the git-log(1)  man page.\n--\nDavid Barr\n"},{"id":"183592","messageId":"20120202120340.GA25190@burratino","threadId":"29515","inReplyTo":"CAFfmPPMc1V97OPHyrZp+p4YUek1c6fCncyj0s1YU9xjxQBCsDA@mail.gmail.com","subject":"Re: How to find and analyze bad merges?","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2012-02-02T12:03:40Z","receivedAt":"2012-02-02T12:03:40Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"David Barr wrote:\n\n> Do the -c --cc or -m flags for git log help in this case?\n> They alter the way merge diffs are presented, as described under Diff Formatting\n> in the git-log(1)  man page.\n\nI suspect Norbert was running into history simplification, so the --full-history\nflag would be the relevant one.\n\nSee the thread [1] for a few relevant side-notes.\n\n[1] http://thread.gmane.org/gmane.comp.version-control.git/188904\n"},{"id":"183593","messageId":"jgduf8$mm3$1@dough.gmane.org","threadId":"29515","inReplyTo":"CAFfmPPMc1V97OPHyrZp+p4YUek1c6fCncyj0s1YU9xjxQBCsDA@mail.gmail.com","subject":"Re: How to find and analyze bad merges?","fromName":"norbert.nemec","fromEmail":"norbert.nemec@native-instruments.de","sentAt":"2012-02-02T12:10:06Z","receivedAt":"2012-02-02T12:10:06Z","isPatch":false,"sender":{"key":"norbert.nemec@native-instruments.de","avatar":null},"body":"Am 02.02.12 12:41, schrieb David Barr:\n> On Thu, Feb 2, 2012 at 10:17 PM, Norbert Nemec\n> <norbert.nemec@native-instruments.de>  wrote:\n>> To be yet more precise:\n>>\n>> My complaint is that you need this kind of sledge-hammer solutions to\n>> analyze the situation. I, as an semi-expert with git did manage to find the\n>> problem without even having to resort to bisect or manually redoing the\n>> merge. My complaint is about the perspective of the medium-experienced user\n>> who is completely puzzled by the fact that a\n>> \"git log<filename>\" silently skips the critical merge commit.\n>\n> Do the -c --cc or -m flags for git log help in this case?\n> They alter the way merge diffs are presented, as described under Diff Formatting\n> in the git-log(1)  man page.\n\nIndeed, these help somewhat. This way, the changes are not hidden, but \ninstead lost in the multitude of trivially-resolved conflicts...\n"},{"id":"183595","messageId":"jgduqg$p9f$1@dough.gmane.org","threadId":"29515","inReplyTo":"20120202120340.GA25190@burratino","subject":"Re: How to find and analyze bad merges?","fromName":"norbert.nemec","fromEmail":"norbert.nemec@native-instruments.de","sentAt":"2012-02-02T12:16:07Z","receivedAt":"2012-02-02T12:16:07Z","isPatch":false,"sender":{"key":"norbert.nemec@native-instruments.de","avatar":null},"body":"Am 02.02.12 13:03, schrieb Jonathan Nieder:\n> David Barr wrote:\n>\n>> Do the -c --cc or -m flags for git log help in this case?\n>> They alter the way merge diffs are presented, as described under Diff Formatting\n>> in the git-log(1)  man page.\n>\n> I suspect Norbert was running into history simplification, so the --full-history\n> flag would be the relevant one.\n\nNot quite.\n\nAs far as I understand it, history simplification hides the whole branch \nif its changes did not end up in the current branch.\n\nWhen I tried it out, the --full-history prevented hiding the \nbugfix-commit itself, but it did not show the critical merge commit in \nthe log.\n\n> See the thread [1] for a few relevant side-notes.\n >\n > [1] http://thread.gmane.org/gmane.comp.version-control.git/188904\n\nAs I understand this thread, the user only requested all commits that \n\"modify a file\". Our merge-commit strictly speaking did not modify the \nfile but simply kept one of the versions, completely swamping all \nmodifications from one branch. Exactly the case that is still not \ncovered by --full-history.\n"},{"id":"183609","messageId":"8489.38.96.167.131.1328195376.squirrel@mail.lo-cal.org","threadId":"29515","inReplyTo":"jgduqg$p9f$1@dough.gmane.org","subject":"Re: How to find and analyze bad merges?","fromName":"Neal Groothuis","fromEmail":"ngroot@lo-cal.org","sentAt":"2012-02-02T15:09:36Z","receivedAt":"2012-02-02T15:09:36Z","isPatch":false,"sender":{"key":"ngroot@lo-cal.org","avatar":null},"body":">> See the thread [1] for a few relevant side-notes.\n>  >\n>  > [1] http://thread.gmane.org/gmane.comp.version-control.git/188904\n>\n> As I understand this thread, the user only requested all commits that\n> \"modify a file\". Our merge-commit strictly speaking did not modify the\n> file but simply kept one of the versions, completely swamping all\n> modifications from one branch. Exactly the case that is still not\n> covered by --full-history.\n\nThe thread was prompted by the difficulty I had in figuring out where a\nco-worker had accidentally squashed changes in a branch that was being\nmerged in; I think that's the same issue that you have described.\n\nRe: the merge: it kept one of the versions, but not the other; I would\nconsider that a change.  This is particularly problematic if you do a \"git\nlog --full-history --simplify-merges\".  The simplified history that is\npresented will not show the merge, even though in the simplified history\nthe merge turns into a regular commit that differs from its parent.  It\nseems that the history is being simplified to the point of being\ninaccurate.\n\nI believe that this is a result checking for TREESAME-ness before the\nhistory simplification occurs, rather than after.  I would love to see\nthis behavior changed, or at the least, an option added to allow the user\nto control it.\n"},{"id":"183650","messageId":"7vr4yduher.fsf@alter.siamese.dyndns.org","threadId":"29515","inReplyTo":"jgdjd1$5mn$1@dough.gmane.org","subject":"Re: How to find and analyze bad merges?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-02-02T20:09:00Z","receivedAt":"2012-02-02T20:09:00Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"norbert.nemec\" <norbert.nemec@native-instruments.de> writes:\n\n>> Bisect?\n>\n> This is not the point: My colleague knew exactly which commit\n> contained the bugfix. The trouble was finding out why this bugfix\n> disappeared even though everything indicated that it was cleanly\n> merged into the current branch.\n\nThen again \"Bisect?\"\n\nI wasn't and I am not suggesting to use Bisect to find the original fix. I\nwas suggesting to use Bisect to find the _merge_ you were looking for.\n"}]}