Take the 2-minute tour ×

I am working on a research to study merges in open source projects.

I recently asked How can I find all the commits that have multiple parents in a Mercurial repository?, and got a very good answer.

Now I need to narrow my query to only find the commits that had conflicts.

With conflicts I mean that the same file was modified in the two contributing commits.

Also, it would be very useful if I can find a mercurial or bash (grep, awk?) command that gives me only those commits in which the same line was modified by the two contributors.

The idea is to find commits that cannot be auto-resolved.

So, How can I find all the merges that had conflicts in a Mercurial repository?

share|improve this question
In case anyone is interested, I asked the same question for Git too: stackoverflow.com/questions/15707769/… –  macrobug Mar 30 '13 at 15:15
Just post some sample input and expected output along with an explanation of the textual transformation without reference to your domain-specific terminology (e.g. "merges", "commits", "parents", "conflicts", "mercurial" probably either don't mean anything or could mean many things to many of the people reading this). It's more likely you'll get a good answer if you can do that than if you expect everyone else to go read a bunch of old posts to try to figure out what your question is about. –  Ed Morton Apr 2 '13 at 15:59
Fair enough Ed. "Commits" are what in other version control systems are called revisions or changesets, which are atomic units of related changes. The "parent" of a commit is another commit that immediately precedes it. With "merges" I mean commits that have multiple parents. A "conflict" happens when two parents modify the same line of code. "Mercurial" is a distributed version control system. Sample input: any considerable sized open source mercurial repository (I have plenty of these). Sample output: a list of commit IDs (e.g. 15691597c1bd120b0b393a9577c183121ea72c2e) –  macrobug Apr 3 '13 at 1:45
@EdMorton If you hover over the "Mercurial" tag, you will see that it refers to a specific version control system where all the terms used in the question have clear and unambiguous meanings. Someone unfamiliar with the system and its terminology will be unable to answer anyway, so there is no point in defining them separately. –  user4815162342 Apr 3 '13 at 12:06
@macrobug - got it, Mercurial sounds a lot like ClearCase, CVS or SVN in tragically allowing multiple concurrent edits of the same file. When I asked for sample input, though, I meant to the awk command you thought might be feasible as that's where my expertise lies. For example if you can get to the point of having some textual output from some Mercurial commands and you just need to parse/organize it appropriately then I could help. I'll keep half an eye on the thread to see if it gets to that point. –  Ed Morton Apr 3 '13 at 12:56
add comment

4 Answers

up vote 1 down vote accepted

For each merge revision, you can retrieve the list of changed files, relative to the first and second parent revisions. Files that appear in both lists are presumably conflicts.

Here's a sample:

for rev in $(hg log -r "merge()" --template '{rev}\n'); do
    hg status --rev "p1($rev)" --rev $rev --no-status | sort > /tmp/p1
    hg status --rev "p2($rev)" --rev $rev --no-status | sort > /tmp/p2
    echo Conflicts in $rev:
    comm -1 -2 /tmp/p1 /tmp/p2

Note: this probably won't cope with files being renamed. You could try adding "--copies" to the "hg status" calls.

share|improve this answer
Thanks Simon! I modified your answer to use hashes instead of integer IDs. –  macrobug Apr 5 '13 at 22:55
add comment

There is no simple way to find these as there is nothing recorded in the merge to indicate whether the merge had conflicts or not.

Note that a file that was modified in two branches does not necessarily constitute a conflict, it will only lead to a conflict if the file is:

  1. Unmergeable (ie. binary or similar)
  2. or, at least one area in the file was changed in both branches

If you change the top of the file in one branch, and the bottom in another, and they are sufficiently far away from each other (usually a couple of lines between changes are enough), then this will merge without a conflict.

Your only option is to replay each merge that contains a file that was changed in both branches, making a note of which merges that mercurial cannot merge without conflict.

Also, I don't know of any way to use the built-in query syntax to find merges where the same file was changed in both branches. I think you'll have to go dig in the log yourself (that is, with some code).

share|improve this answer
Your only option is to replay each merge[...] My answer to the git variant of the question implements this approach. The OP seems to be looking for the equivalent code for mercurial. –  user4815162342 Apr 2 '13 at 14:16
add comment

You can use the filters to isolate all merged files and from that their parents. But you would then need to diff the parents to see if there are any merge conflicts.

share|improve this answer
add comment
  1. Yes, you have to replay each merge between merge-parents
  2. After merge check return-code of merge

Returns 0 on success, 1 if there are unresolved files.

share|improve this answer
add comment

Your Answer


