You are essentially looking to identify whether some merge is an evil merge.
Currently, the only way to tell for sure whether someone made an evil merge in Git is to re-perform the merge. You do the same merge yourself, and you know whether or not you have done an evil merge. You can then compare your merge result to theirs. If you did a non-evil merge (a "good merge"? an "angelic merge"?) and your result differs from theirs, they must have done an evil merge.
This method requires a lot of human intervention so it's not really suitable for widespread use. You can, as Sousou noted / linked-to, use git merge-tree
to determine whether the original merge had merge conflicts that had to be resolved. If not, Git itself could just do the merge automatically somewhere and compare that to the committed merge. This could be automated.
As the word could above suggests, Git doesn't actually do this now. There's a new merge strategy in the works (see this answer to When would you use the different git merge strategies?), that would act as a nice bit of enabling technology, and once it's in place, there are some vague but reasonably-straightforward-looking plans to offer this as an option (it will be somewhat compute-intensive but really quite handy, I think).
Even once all the above has landed, there's still one stumbling block. How big it would be in practice, I don't know. You'll see it if and when you use the "re-perform the merge" method manually. In particular, when someone runs git merge
, they can provide options, such as -s ours
or -X ours
or -X find-renames=75
. These options are not recorded anywhere. When you (or Git) go to re-perform a merge, what options should you supply? Fortunately, if you're redoing the merge by hand, you (presumably) know what options you should supply if any.
So, if you want to test for an evil merge, simply check out the first-parent commit of the two tip commits as a detached HEAD and run git merge options hash
, supplying the desired options and the hash ID of the second tip commit. Resolve any conflicts (correctly of course); commit the result if you like; and then compare this result to the existing merge commit.
Note that git log
already shows the (abbreviated) hashes of the two parents, but if you like, you can just run git rev-parse hash^@
. The hat-at (^@
) suffix means all parents of the given commit. They come out in order, so the first hash ID listed is the first parent of the merge, and the second hash ID listed is the other parent of the merge. (For an octopus merge, git rev-parse
will list more than two parents, but this won't be an octopus merge.)