{"thread":{"id":"26083","subject":"Correctly detecting modified paths in merge commits?","startedAt":"2010-12-16T16:54:11Z","lastAt":"2010-12-16T18:33:38Z","messageCount":2,"participants":["Dun Peal","Jakub Narebski"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"158212","messageId":"AANLkTimsHZ543B7XWS6taa0w2Vc4huznx3UMs4Ejg3af@mail.gmail.com","threadId":"26083","inReplyTo":null,"subject":"Correctly detecting modified paths in merge commits?","fromName":"Dun Peal","fromEmail":"dunpealer@gmail.com","sentAt":"2010-12-16T16:54:11Z","receivedAt":"2010-12-16T16:54:11Z","isPatch":false,"sender":{"key":"dunpealer@gmail.com","avatar":"https://gravatar.com/avatar/42f3e6a1166eb44e33f24c20ccbe809fa8591413f366dfe3755c8a8d4935ace9?d=mp&s=160"},"body":"Hi.\n\nWe wrote a post-receive hook that alerts users (via email) when\nspecific paths are modified by their peers. The implementation is\npretty simple: whenever a new commit is made, we ask git for the full\nlist of files modified by that commit:\n\n  git diff --name-only <COMMIT HASH>^!\n\nThis works well for regular commits, but breaks for merge commits.\n\nFor example, suppose we have the following basic merge scenario:\n\n  B\n / \\\nA   D\n \\ /\n  C\n\nRoot A was branched to B and C, then merged into commit D.\n\nProblem is, the diff for D^! will include all the changes introduced by C.\n\nOne obvious solution is to simply ignore merge commits, by parsing\n`git cat-file commit D` and discarding all commits with parent count >\n1. But merge commits may actually contain legitimate modified files if\nthere were any conflict resolutions.\n\nSo what's the best solution for this problem, oh wise Git wizards?\n\nThanks, D.\n"},{"id":"158213","messageId":"m37hgdm84r.fsf@localhost.localdomain","threadId":"26083","inReplyTo":"AANLkTimsHZ543B7XWS6taa0w2Vc4huznx3UMs4Ejg3af@mail.gmail.com","subject":"Re: Correctly detecting modified paths in merge commits?","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-12-16T18:33:38Z","receivedAt":"2010-12-16T18:33:38Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Dun Peal <dunpealer@gmail.com> writes:\n\n> We wrote a post-receive hook that alerts users (via email) when\n> specific paths are modified by their peers. The implementation is\n> pretty simple: whenever a new commit is made, we ask git for the full\n> list of files modified by that commit:\n> \n>   git diff --name-only <COMMIT HASH>^!\n> \n> This works well for regular commits, but breaks for merge commits.\n\nNote that <commit>^! is *range* specifier, and 'git diff' really takes\ntwo *endpoints*.  \n\n>From git-diff(1) manpage.\n\n    For a more complete list of ways to spell <commit>, see  \"SPECIFYING\n    REVISIONS\" section in gitrevisions(1). However, \"diff\" is about \n    comparing two _endpoints_, not ranges, and the range notations  \n    (\"<commit>..<commit>\"  and  \"<commit>...<commit>\")  do not mean a\n    range as defined in the \"SPECIFYING RANGES\" section in gitrevisions(1).\n\n<commit>^1 means include given commit but exclude all of its parents\n(see gitrevisions(7)).\n\nFor a merge commit r1^! means r1 ^p1 ^p2 (where p1 and p2 are parents\nof r1), which for git-diff probably means \"git diff p1 r1\".\n  \n \n> For example, suppose we have the following basic merge scenario:\n> \n>   B\n>  / \\\n> A   D\n>  \\ /\n>   C\n> \n> Root A was branched to B and C, then merged into commit D.\n> \n> Problem is, the diff for D^! will include all the changes introduced by C.\n\nSee above.\n\nTry \n\n  $ git diff-tree --name-only -c <COMMIT HADH>\n\ninstead.  '-c' is to show merge commit as combined diff (noting changes\ndifferent from both parents).  I'm not sure if this is what you want.\n\nThere is alwats '--cc' or '-m' instead of '-c'.\n \n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"}]}