3

1

Hello,

We have been deployed fully and using mercurial/kiln for about 1 month now in our team of about 30 engineers, having transitioned from an older centralized version control system.

A couple of times, the "hg merge" has selected what we think is the "wrong" change. I have been able to reproduce a recent incident where hg merge reported no conflicts but we believe selected the wrong change, and we are confused and do not understand the logic.

I was trying to find the actual "algorithm" used by mercurial during its merge, but google was not my friend on this.

Anyhow, does anyone know how mercurial selects changes during the automatic hg merge?

thank you very much,

flag
If you can reproduce the situation, it would be nice to know about it, in case I end up with something similar myself. Can you post some steps to reproduce the problem? – Lasse V. Karlsen Feb 7 2011 at 11:38

2 Answers

6

To perform merges:

  1. Mercurial first finds the most recent common ancestor between the two changesets (let's call them A and B) you are merging. This is considered the base.
  2. Any files that have not been modified since the base are not in conflict.
  3. If a file has been modified only in A or B's development line, then that modification is taken, and is not in conflict.
  4. If a file has been modified in A and renamed in B (or vice-versa), then B's rename is adopted with A's changes, and is not a conflict.
  5. If a file is renamed in both A and B, deleted in one but modified in the other, or some other variant of those, Mercurial notes it as a tree conflict, and you must manually resolve.
  6. If a file has been modified on both A and B, Mercurial finds a merge strategy based on the content of the file. If your file is anything but ASCII or Unicode text, Mercurial will probably note the file as conflicted. Assuming the file is text:
    1. Mercurial will first attempt to perform an internal three-way merge. The general idea is that if the changes in A and B from the LCA do not overlap, then they are considered non-conflicting, and can be adopted.
    2. If there are conflicting ranges, Mercurial instead hands off the merge to the three-way merge tool you have requested. For TortoiseHg, that default is kdiff3. kdiff3 is frequently able to merge files successfully that Mercurial's internal merge tool cannot. If kdiff3 believes it has successfully merged, then it will tell Mercurial so, and will record that as a successful merge.
    3. Further, if you have conflict in kdiff3, but you resolve them yourself and save your changes, then that also will be counted as a successful merge, and not show up as an unresolved conflict.
    4. A failure status code from the 3-way merge tool, or the absence of one, will leave the file in a conflicted state.

If you would like to contact us privately to talk about the specific instance you hit, or if you can provide an example of what you think is erroneous on a dummy repository, I can probably help you figure out why Mercurial is merging the way it is.

link|flag
I have tried for over an hour now to reproduce on a dummy repo... so far no joy. I looked back in the history and found that the exact line had been manually modified as part of a previous merge commit, and was NOT modified in the parents ( i.e. the person did a merge AND an unrelated change in the same merge commit). Could that be part of this? I tried to reproduce the same in a dummy repo, and still "hg merge" always reported the conflict.... – M. Esh Feb 14 2011 at 22:55
0

Does this help?

http://mercurial.selenic.com/wiki/Merge

link|flag

Your Answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.