Dealing with Text Conflicts in Bazaar Version Control

This post is a follow-on from a previous post that formed a basic introduction to Bazaar version control. If you'd like to find out more about Bazaar then you can also read about it on the official Bazaar website

There will come a time in any project when you will have deal with conflicts caused by the merge process the most common of these are text conflicts. The following post will walk you through the process of dealing with text conflicts in a file called styles.css after updating your branch. In Bazaar when a text conflict is encountered, three files are created; styles.css.BASE contains the common base, styles.css.THIS contains your changes, styles.css.OTHER contains the content from the tree.

That sounds quite involved so to demonstrate it lets create a conflict and work through resolving it.

The Conflict

So first off I caused a conflict by deliberately creating problems for when a file was updated between two separate checkouts. The result was a message like this when running bzr update:

Text conflict in styles.css
1 conflicts encountered.
Updated to revision 4

Runnning ls -la in the current directory reveals the following files:

-rw-r--r--   1 muffin  users  131 Jun  5 01:59 styles.css
-rw-r--r--   1 muffin  users   39 Jun  5 01:59 styles.css.BASE
-rw-r--r--   1 muffin  users   42 Jun  5 01:59 styles.css.OTHER
-rw-r--r--   1 muffin  users   59 Jun  5 01:59 styles.css.THIS

The Diff

So let's run a diff. We can either run bzr's built-in diff or we can use a graphical diff. For completeness let's look at bzr's built-in diff first.

Running bzr diff (diffs the last revision) gives me the following output:

=== modified file 'styles.css'
--- styles.css  2007-06-05 00:58:51 +0000
+++ styles.css  2007-06-05 00:59:55 +0000
@@ -1,7 +1,17 @@
 .test{
+<<<<<<< TREE
+
+
+display: block;
+
+
+width: 10px;
+height: 20em;
+=======
 display: block;
 height: 9px;

+>>>>>>> MERGE-SOURCE

 }

To resolve the conflict itself you have two options.

Option 1: Resolve the conflict manually as text

This is very simple and if you love your command line text editor you can simply edit the file, choose the changes that you want and remove the merge markers (e.g. >>>>>>> MERGE-SOURCE). To complete the process you need to run bzr resolve styles.css to cleanup the merge files. Bzr automatically detects the conflict you have resolved and will auto resolve it for you.

Option 2: Resolve the conflict using a graphical diff application

I'm using FileMerge which is built-in to Xcode on the mac (there are graphical diff apps for windows and linux as well). If you don't have developer tools installed you can download them from Apple's website.

So by dragging styles.css.THIS, styles.css.OTHER and styles.css.BASE into my diff app I can see the difference between the files. If you're using FileMerge to add the BASE file you need to resize the file dialogue and drag or open the BASE file as an ancestor.

It's worth noting at this point that it's also possible to use the command 'opendiff' on macs to open FileMerge from within terminal. As an example you can use something like this:

opendiff file.THIS file.OTHER -ancestor file.BASE

Now as you can see this faked conflict is a fairly contrived example but should give the idea as to how to resolve the differences between the tree and your modifications.

With FileMerge you can select each difference and state whether you want to choose the left or right side or both. Once you have decided which changes you'd like to keep you can then export the manually merged file.

So I'll do that now and save it over the top of styles.css. Next I can run bzr resolve to clear the conflict now that I have resolved it manually. This will remove them styles.css.OTHER and styles.css.BASE files.

And that's all there is to it. Obviously in reality the diffs that you will have to manually edit will be far more complicated but the process is the same.

For more info on other conflicts see the Bazaar docs: http://doc.bazaar-vcs.org/latest/en/user-guide/conflicts.html