How to resolve Subversion Conflicts

Wednesday 4 July 2007

If there's more than one person working on a project, chances are (although slim) that at some point two developers work on the same piece of code and check it in. To clarify, let me give you an example.

The repository is currently at revision 5 and contains a file named 'README'. Revision 5 of that file contains a single line: 'This is a README file'.

Now, both you and your colleague check out r5 and edit README. Your colleague changes the line to 'This is a documentation file' and commits it back to the repository, which is bumped to revision 6.

You're an island, and have no clue about the new revision being created. You just happily write away and change the README file to: 'This is fun stuff!'.

When you commit your changes, you'll get an error message:

$ svn commit -m "Updated README"
Sending    README
Transmitting file data .svn: Commit failed (details follow):
svn: Out of date: '/myproject/README'

~ This is good. Subversion has detected that the file you want to commit has changed since you last updated it. Update the file to get it up-to-date again.

$ svn update
C   README
Updated to revision 6.

The 'C' indicates there is a conflict with the README file, and Subversion does not know how to solve this. You are called in to help.

If you now take a look at README, you'll notice that there are several markers that indicate what parts of the code are conflicting. You can easily see what you changed, and what has changed in the repository:

<<<<<<< .mine
This is fun stuff!
=======
This is a documentation file
>>>>>>> .r6

What are your options?

You have three options for resolving the conflict. Whatever you choose, make sure you confer with your colleague on the matter.

1. Scrap your changes, and go with the current work from your colleague.

This is the easiest solution. All you have to do is revert the changes you made, and update your working copy:

$ svn revert README
Reverted 'README'
$ svn update README
At revision 6.

2. Keep your changes, and dump whatever your colleague did.

Performing a simple 'ls' will show you that there are four files related to this conflict:

  • README – the original with markers
  • README.mine – your version
  • README.r5 – the original your worked with
  • README.r6 – the most update version from your colleague

To check in your changes, copy your version over the original and tell Subversion you have resolved the conflict.

$ cp README.mine README
$ svn resolved README
Resolved conflicted state of 'README'

The 'resolved' command will clean up all the special files that were generated.

3. Merge both version to a new version

If you choose this option, you will have to manually edit README. Remove the markers and add whatever you need to add here.

Subversion won't let you commit this file, so you'll have to mark it as 'resolved' as we saw during option 2:

$ svn resolved README
Resolved conflicted state of 'README'

Before you rush ahead

With option 1, you're done. With options 2 and 3 there is some more work to do, because you didn't commit your changes yet. Because we're dealing with conflicts here, I recommend you don't just commit to your repository, but follow a slightly different route.

First, update your working copy (again) to make sure you have all the latest, and are not trying to check in any more conflicting code. If any conflicts pop-up, fix these first.

Now, run your tests to make sure everything is working as it should.

When all is clear, commit your changes to your repository as you normally would.

Done. Problem solved.

Did you enjoy this post? Your generosity is much appreciated.