threads / discuss / 26083

Correctly detecting modified paths in merge commits?

Subject: Correctly detecting modified paths in merge commits?

## tl;dr

2 messages between Dec 16, 2010 and Dec 16, 2010.

replies: 1people: 2as markdown or json

Dun Peal· Dec 16, 2010, 16:54 UTC · lore
Hi.

We wrote a post-receive hook that alerts users (via email) when specific paths are modified by their peers. The implementation is pretty simple: whenever a new commit is made, we ask git for the full list of files modified by that commit:

  git diff --name-only <COMMIT HASH>^!
This works well for regular commits, but breaks for merge commits.
For example, suppose we have the following basic merge scenario:
  B
 / \
A   D
 \ /
  C
Root A was branched to B and C, then merged into commit D.
Problem is, the diff for D^! will include all the changes introduced by C.
One obvious solution is to simply ignore merge commits, by parsing
`git cat-file commit D` and discarding all commits with parent count >
1. But merge commits may actually contain legitimate modified files if
there were any conflict resolutions.
So what's the best solution for this problem, oh wise Git wizards?
Thanks, D.
Jakub Narebski· Dec 16, 2010, 18:33 UTC · re: Dun Peal · lore

Re: Correctly detecting modified paths in merge commits?

Dun Peal <dunpealer@gmail.com> writes:
Show 8 quoted lines
> We wrote a post-receive hook that alerts users (via email) when
> specific paths are modified by their peers. The implementation is
> pretty simple: whenever a new commit is made, we ask git for the full
> list of files modified by that commit:
> 
>   git diff --name-only <COMMIT HASH>^!
> 
> This works well for regular commits, but breaks for merge commits.

Note that <commit>^! is *range* specifier, and 'git diff' really takes two *endpoints*.

>From git-diff(1) manpage.
    For a more complete list of ways to spell <commit>, see  "SPECIFYING
    REVISIONS" section in gitrevisions(1). However, "diff" is about 
    comparing two _endpoints_, not ranges, and the range notations  
    ("<commit>..<commit>"  and  "<commit>...<commit>")  do not mean a
    range as defined in the "SPECIFYING RANGES" section in gitrevisions(1).

<commit>^1 means include given commit but exclude all of its parents (see gitrevisions(7)).

For a merge commit r1^! means r1 ^p1 ^p2 (where p1 and p2 are parents
of r1), which for git-diff probably means "git diff p1 r1".
  
 
Show 11 quoted lines
> For example, suppose we have the following basic merge scenario:
> 
>   B
>  / \
> A   D
>  \ /
>   C
> 
> Root A was branched to B and C, then merged into commit D.
> 
> Problem is, the diff for D^! will include all the changes introduced by C.
See above.
Try 
  $ git diff-tree --name-only -c <COMMIT HADH>

instead. '-c' is to show merge commit as combined diff (noting changes different from both parents). I'm not sure if this is what you want.

There is alwats '--cc' or '-m' instead of '-c'.
 
-- 
Jakub Narebski
Poland
ShadeHawk on #git

← back to recent threads