CIT 594 Merging Files with KDiff3
Spring 2011, David Matuszek

Kdiff3 is a file diff/merge program that is available on Windows, Linux, and Mac. It seems to be the most popular such program used by people who use Mercurial. I found KDiff3 very confusing at first, so this page is a brief introduction. Other diff/merge programs are somewhat similar, so if you understand this page, you should be able to adapt the ideas to those programs.

Here's what I did:

  1. First, I created a directory initial-repo and a file initial-repo/test-file.txt. I'll treat this as the central repository, such as might be stored on Bitbucket.
  2. I made the directory into a Mercurial repository:
    1. C:\Documents and Settings\matuszek>cd initial-repo
    2. C:\Documents and Settings\matuszek\initial-repo>hg init
    3. C:\Documents and Settings\matuszek\initial-repo>hg add
      adding test-file.txt
    4. C:\Documents and Settings\matuszek\initial-repo>hg commit
    5. The “commit” required me to enter a commit message: This is the initial version of the test file.
  3. I cloned this repository twice, into new directories repo1 and repo2.
    1. C:\Documents and Settings\matuszek\initial-repo>hg clone . ..\repo1
      updating to branch default
      1 files updated, 0 files merged, 0 files removed, 0 files unresolved
    2. C:\Documents and Settings\matuszek\initial-repo>hg clone . ..\repo2
      updating to branch default
      1 files updated, 0 files merged, 0 files removed, 0 files unresolved
  4. I edited the files in the two directories, making different changes in each.
  5. Still in repo1, I tried the usual commit-pull-merge-update sequence:
    1. C:\Documents and Settings\matuszek\repo1>hg commit
      Entered a commit message: "Changed the second paragraph (and a few other things)."
    2. C:\Documents and Settings\matuszek\repo1>hg pull
      pulling from c:\Documents and Settings\matuszek\initial-repo
      searching for changes
      no changes found

      Since there were no changes in the central repository (../initial-repo) since the last time I got files from it, no merge is needed.
    3. C:\Documents and Settings\matuszek\repo1>hg push
      pushing to c:\Documents and Settings\matuszek\initial-repo
      searching for changes
      adding changesets
      adding manifests
      adding file changes
      added 1 changesets with 1 changes to 1 files
  6. Now to move to repo2 and try the same thing.
    1. C:\Documents and Settings\matuszek\repo1>cd ..\repo2
    2. C:\Documents and Settings\matuszek\repo2>hg commit -m "Other random changes."
    3. C:\Documents and Settings\matuszek\repo2>hg pull
      pulling from c:\Documents and Settings\matuszek\initial-repo
      searching for changes
      adding changesets
      adding manifests
      adding file changes
      added 1 changesets with 1 changes to 1 files (+1 heads)
      (run 'hg heads' to see heads, 'hg merge' to merge)
    4. C:\Documents and Settings\matuszek\repo2>hg heads
      changeset: 2:fe34ba6b9357
      tag: tip
      parent: 0:191cf2013d66
      user: Dave at work <matuszek@my email address>
      date: Wed Apr 06 12:56:44 2011 -0400
      summary: Changed the second paragraph (and a few other things).

      changeset: 1:53aec1041a6e
      user: Dave at work <matuszek@my email address>
      date: Wed Apr 06 13:24:17 2011 -0400
      summary: Other random changes.
    5. C:\Documents and Settings\matuszek\repo2>hg merge
      merging test-file.txt
      Nothing more happens for several seconds, then:

      kdiff3

      Base” is the original file, and parent1 and parent2 are repo1/test-file.txt and repo2/test-file.txt, respectively. At this point, Mercurial has merged all the insertions, deletions, and changes where there are no conflicts, and what you are expected to do is to resolve all the remaining conflicts. Right clicking on a conflict brings up a dialog box,
      select a, b, or c
      so you can choose which version to keep.
      Important:
      • You cannot save the file until all conflicts have been resolved.
      • You can edit the result (in the lower pane).
      • kdiff3 has no undo facility!
      When you save and quit, Mercurial responds with
      0 files updated, 1 files merged, 0 files removed, 0 files unresolved
      (branch merge, don't forget to commit)
  7. So, finishing up:
    1. C:\Documents and Settings\matuszek\repo2>hg commit -m "Merge."
      Note: In your “commit comments,” it is important to tell what changes have been made, in case you ever need to go back to an earlier version. When merging, however, there is often nothing useful to say.
    2. C:\Documents and Settings\matuszek\repo2>hg push
      pushing to c:\Documents and Settings\matuszek\initial-repo
      searching for changes
      adding changesets
      adding manifests
      adding file changes
      added 2 changesets with 2 changes to 1 files
  8. Final status:

    repo2:
    I did the commit-pull-merge in the repo2 directory.
    Now, pull and a successful merge will just change the repository, not the working directory; you have to also do an update to get the merged result up into your working directory.
    However, the above demonstrates an unsuccessful merge. I used kdiff3 to complete the merge, and this left the merged result in the repo2 working directory. I had to do a commit to put the result into the repo2 repository. This is “backwards” from the usual case.

    initial-repo: After the commit, I did a push from repo2. This put a changeset in the repository in initial-repo, but did not change the initial-repo working directory. The changes are available there, but the files themselves haven't been updated.

    repo1: The last thing that was done here was to edit the test-file.txt file. Nothing has changed. However, the latest and greatest version is waiting for us in initial-repo, should we decide to pull:
    1. C:\Documents and Settings\matuszek\repo2>cd ../repo1
    2. C:\Documents and Settings\matuszek\repo1>hg incoming
      comparing with c:\Documents and Settings\matuszek\initial-repo
      searching for changes
      changeset: 2:53aec1041a6e
      parent: 0:191cf2013d66
      user: Dave at work <matuszek@cis.upenn.edu>
      date: Wed Apr 06 13:24:17 2011 -0400
      summary: Other random changes.

      changeset: 3:bc819bc9912f
      tag: tip
      parent: 2:53aec1041a6e
      parent: 1:fe34ba6b9357
      user: Dave at work <matuszek@cis.upenn.edu>
      date: Wed Apr 06 17:14:45 2011 -0400
      summary: Merge.