Merge Tracking with Subversion (pre 1.5.0)

Merge tracking is a feature of some revision control software. This feature remembers which merges have taken place, allowing you to later see what merges have been done and what else needs to be merged. The feature was not part of Subversion until version 1.5.0. However, not all projects are using the latest version of Subversion. Fortunately, for projects that are using older versions of subversion, there is still the svnmerge script. If your project is using the latest version of Subversion, it should already have similar functionality.

Initialising Merge Tracking

To use the script, the branch should be made by using the svn cp command. The branch is usually created from trunk. Once the branch has been created and checked out, you must tell it to initialise your checkout before making any changes. It is also important to execute the initalisation command at the top level directory of the branch. For example, lets say you check out the file:///repository/branch/example to /home/user/work so that you now the contents of the branch is located in /home/user/work/example. Then you should change to the directory /home/user/work/example before executing the initialisation command:

svnmerge init

If you had already made any changes, you should receive an error similar to the following:

svnmerge: “.” has local modifications; it must be clean

If it was successful, you should now have a file svnmerge-commit-message.txt in the directory. This file is used by the script to track the merges that are performed and can also be added to your repository so that you do not lose your merge tracking information if you delete your current checkout. The contents of the file is also human readable, so you can view it to see what has been merged.

Finding Out What is Available for Merging

Now that the svnmerge has initialised merge tracking for the directory, you can find what changes from trunk need to be merged. The avail command will tell you which versions need to be merged. To view the log messages of the versions that need to be merged, you can simply use:

svnmerge avail –log

Omitting the “–log” option will cause svnmerge to output just the revision numbers that need to be merged. The avail command also has the option “–diff” to output the differences that need to be applied. If the initialisation was not properly done, you might receive the error:

svnmerge: no integration info available

Another message that you might receive is when you have created a branch from another branch. For example, if you create branch b from a and then c from b and you executed the command on branch c, you would receive an error message that is similar to the following:

svnmerge: multiple sources found. Explicit source argument (-S/–source) required.

The merge sources available are:

/trunk

/branch/test

The problem here is that svnmerge needs to know which of the parent branches to compare branch c with. As suggested in the message, using the “-S” option will tell svnmerge which branch to compare with.

Merging to the Branch

To perform the merge, you just have to use the merge command, as follows:

svnmerge merge

Once the command has been executed, the file svnmerge-commit-message.txt will be updated with latest merge information. Note that because this file is updated when the script is called on to perform the merge, it will NOT detect any merges that you may have performed manually. Should you perform a merge without using svnmerge, you can try executing the merge with svnmerge to update the file. Alternatively, the merge command has a “-M” command to record a merge without actually performing the merge. The merge command also allows you to specify the revisions that are merged. The option for this is “-r”.

Merging Back to Parent

After you complete making changes on the branch, the script can also be used to merge the changes back to the parent branch. To do this, first change to the top level directory where the parent branch was checked out (similar to what was done in Initialising Merge Tracking). Merge tracking needs to be initialised again. Beware that if you have a svnmerge-commit-message.txt file in the directory, it will be overwritten. This path to the branch where the changes were made needs to also be specified, by using the following form of the initialising command:

svnmerge init [path to branch]

While staying in the same directory, execute the merge command to merge the changes back. Again, depending on the number of branches created from the parent, it may be necessary to specify the source branch if it complains about multiple sources (see Finding Out What is Available for Merging). Note that when merging back to the parent, you do not have to execute the initialisation command at the location of the branch.

Preventing Specific Versions From Being Merged

After executing the avail command, you might discover revisions that you might not want to merge. Revisions that should never be merged can be blocked using:

svnmerge block -r [revisions to block]

When you execute the merge again, you should find that the specified revisions are left out of the merge. Note that omitting the “-r” option and the revisions will cause all available revisions to be added to the blocked list. This is also reflected in the output from executing the avail command.

If you later decide would like to make the revision available for merging later, you can use the unblock command.

svnmerge unblock -r [revisions to unblock]

Again, omitting the “-r” and listing the revisions altogether will unblock all revisions. Should you also forget which revisions were previously blocked, you can examine the property svnmerge-blocked.

Finding Out What has Been Merged

After having committed the merges, you might want to view the merges that have been previously performed. This viewable with the integrated command, which can be used like this:

svn integrated –log

Similar to the avail command, omitting the “–log” option will cause to print out just revision numbers and “–diff” can be used to view the differences. The versions that have been merged are also recorded in the property svnmerge-integrated.