Distinguishing trivial and non-trivial merge commits

5 messages, 3 authors, 2016-06-15 · open the first message on its own page

Distinguishing trivial and non-trivial merge commits

From: Eli Barzilay <hidden>
Date: 2016-06-15 22:48:43

I'm trying to get a goot notification script, and got stuck with merge
commits.  My script shows a list of modifications for each commit
(based on the diffstat output) -- and if I show all commits, then
merges are misleading in that a quick glance through the email makes
it look like a lot more was touched.  Using `--no-merges' helps in
avoiding the confusing parts, but that's dangerous in omitting
non-trivial merges too -- and those are probably even more worth
noting than other changes (just because they'll highlights changes
that are "hotter" in the sense of more people working on that code).

The only way I've seen to distinguish the two is to use `git show' and
see if there is no diff output (eg, "git show --pretty=format: $rev").
But that doesn't help in getting the list of modified files.  So I add
`--stat' to that, and that goes back to showing all files again, the
same stuff that "git diff $rev^!" shows.

Is there *any* way to get `git diff --stat' to do the same thing that
`git show' does?  (Or a way to get `git show --stat' not show all
files again...)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Re: Distinguishing trivial and non-trivial merge commits

From: Jonathan Nieder <hidden>
Date: 2016-06-15 22:48:44

Eli Barzilay wrote:
Using `--no-merges' helps in
avoiding the confusing parts, but that's dangerous in omitting
non-trivial merges too -- and those are probably even more worth
noting than other changes (just because they'll highlights changes
that are "hotter" in the sense of more people working on that code).

The only way I've seen to distinguish the two is to use `git show' and
see if there is no diff output (eg, "git show --pretty=format: $rev").
But that doesn't help in getting the list of modified files.
Maybe --name-only or --name-status can help.

Note that most conflicts will not show up here: if the merge result
matches either parent, then git diff --cc and friends will not
consider it interesting at all.  A command to list conflicts and their
resolutions would be expensive but valuable, I think.  A naïve
implementation would involve redoing the merge.

[...]
Is there *any* way to get `git diff --stat' to do the same thing that
`git show' does?  (Or a way to get `git show --stat' not show all
files again...)
A “merge diffstat” sounds like an interesting idea, but the detailed
semantics are not obvious to me (maybe separate counts for nontrivial
added and removed lines from each parent?).

Thanks for the food for thought,
Jonathan

Re: Distinguishing trivial and non-trivial merge commits

From: Eli Barzilay <hidden>
Date: 2016-06-15 22:48:44

On May  2, Jonathan Nieder wrote:
Maybe --name-only or --name-status can help.

Note that most conflicts will not show up here: if the merge result
matches either parent, then git diff --cc and friends will not
consider it interesting at all.
Isn't that a good definition of a trivial commit?  I'm not talking
about the whole commit -- just any file that is not identical to one
of its parents.

A command to list conflicts and their resolutions would be expensive
but valuable, I think.  A naïve implementation would involve redoing
the merge.
[...]
A “merge diffstat” sounds like an interesting idea, but the detailed
semantics are not obvious to me (maybe separate counts for
nontrivial added and removed lines from each parent?).
OK, thanks for clarifying that.  For my purpose, I basically just want
to know whether there was manual tweaking involved in the merge.  (For
my thing I don't even need to see those changes, since I show the
overall push diff only.)  What I ended up doing is pretty bad:

  git show --pretty=short --name-only "$r" | grep -q '^Merge: '
    --> test if it's a merge commit

  git show --pretty=format:"" --name-only "$r" | grep -q "."
    --> test if it's trivial

  git show --pretty=format:"" "$r" | diffstat -p1
    --> get the diffstated output

(My script generally "compensates" for git being fast by running a ton
of them for each email...)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Re: Distinguishing trivial and non-trivial merge commits

From: Jakub Narebski <hidden>
Date: 2016-06-15 22:48:44

Eli Barzilay [off-list ref] writes:
OK, thanks for clarifying that.  For my purpose, I basically just want
to know whether there was manual tweaking involved in the merge.  (For
my thing I don't even need to see those changes, since I show the
overall push diff only.)  What I ended up doing is pretty bad:
Well, the compact combined output is thought in such way that 
"git diff --cc" should be empty except for evil merges, when change
comes from neither of parents.  See description of --cc format in
git-diff(1) manpage.

The other side is "git diff --raw" output for merges.
-- 
Jakub Narebski
Poland
ShadeHawk on #git

Re: Distinguishing trivial and non-trivial merge commits

From: Jonathan Nieder <hidden>
Date: 2016-06-15 22:48:44

Eli Barzilay wrote:
On May  2, Jonathan Nieder wrote:
quoted
Note that most conflicts will not show up here: if the merge result
matches either parent, then git diff --cc and friends will not
consider it interesting at all.
Isn't that a good definition of a trivial commit?  I'm not talking
about the whole commit -- just any file that is not identical to one
of its parents.
[...]
For my purpose, I basically just want
to know whether there was manual tweaking involved in the merge.
diff --name-only follows exactly the example heuristic you described.
It still does not catch all manual merge resolutions[1].

Sometimes two branches introduce different changes to completely
separate parts of a file.  This is not a conflict, and diff --cc will
correctly report the merge as trivial (whereas diff --name-only does
not pay enough attention to do the same).

On the other hand, sometimes two branches introduce conflicting
changes, but the correct resolution for each conflict hunk is to pick
one as winner.  Though simple, this can be error-prone, because
rejecting one change from branch A might end up breaking another
change that was accepted from the same branch.  diff --cc examines
only the selected revision and its parents and for all it knows, this
is just another trivial merge.
 git show --pretty=format:"" --name-only "$r" | grep -q "."
   --> test if it's trivial
I would have expected

	git show --name-only --exit-code --quiet "$r"

to take care of this, but apparently it always exits zero.  Probably
no one had tried it before.
(My script generally "compensates" for git being fast by running a ton
of them for each email...)
:)

Jonathan

[1] http://thread.gmane.org/gmane.comp.version-control.git/89415
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help