Understanding the merging in Subversion

Understanding the merging in Subversion

While the basic work cycle of update/resolve/commit in Subversion is easy peasy for almost everyone, merge is a lot more confusing. This post shows how the common merging tasks can be accomplished using Subclipse in Eclipse with the understanding of the merging in terms of fundamental Subversion functionalities.

A Subversion merging is basically the process of finding the differences between an initial (left) repository tree and a final (right) repository tree, and applying the differences to the current working copy as local changes. If there was no local change in the working copy before the merging, which should always be the case, the local changes in the working copy thereafter can then be either committed or reverted as the effect of the merging.

Let us look at how the concept of merging is applied in a task that merges a branch back into the trunk where the branch was created from. A branch B, when it was created in revision r, was a cheap copy of a trunk T. So we have B(r) = T(r). After the branch is finished, the revision is r'. Denote the local changes in the branch and the trunk as B(r'-r) and T(r'-r), respectively; The repository trees become B(r') and T(r'). As a best practice, developers who worked in the branch have merged local changes in the trunk into the branch frequently during the development (to make merging the branch back into the trunk easier when the branch is finished). So we actually have B(r') = B(r) + B(r'-r) + T(r'-r) and T(r') = T(r) + T(r'-r). From the equations, we can infer that the developers merged the local changes in the trunk, T(r'-r) = T(r') - T(r), into the branch by equivalently (it was actually done continuously through multiple mergings of small pieces) specifying the initial repository tree as T(r) and the final repository tree as T(r'). Of course, the working copy was the branch. Now we want to merge the branch back so that the trunk can have the local changes in the branch. Be aware that the symmetric approach specifying the initial repository tree as B(r), the final repository tree as B(r') and the working copy as the trunk does not work. Because B(r') - B(r) = B(r'-r) + T(r'-r), where T(r'-r) has already been in the trunk. It does not make sense to merge it again. Say, T(r'-r) contains adding a file. Merging the same T(r'-r) again results in adding the file again, causing a tree conflict. What the trunk indeed needs is B(r'-r) = B(r') - B(r) - T(r'-r) = B(r') - T(r) - T(r'-r) = B(r') - [T(r) + T(r'-r)] = B(r') - T(r'). Thus specifying the initial repository tree as T(r'), the final repository tree as B(r') and the working copy as the trunk will work. This is the fundamental usage and the asymmetric nature of a Subversion merging.

In Eclipse, right click on a project, and choose the menu item Team > Merge..., to bring up the Subclipse GUI:

Fig. 1.  The options of merging in Subclipse.

The fourth option "Merge two different trees" is the fundamental usage as we have discussed. To merge changes from the trunk of a branch into the branch, first make sure the current working copy is the branch (switch/checkout), then use the following configuration, where the From Revision, say 100, is the starting revision (not inclusive) of the changes you want to merge. For the first merging, it is the revision when the branch is created; For subsequent mergings, it is the To Revision of the last merging.

Fig. 2.  The fourth option that merges changes from the trunk of a branch into the branch.

To merge changes from the branch into the trunk when the branch is finished, first make sure all the changes in the trunk since the branch is created has been merged into the branch, then make sure the current working copy is the trunk, finally use the following configuration,

Fig. 3.  The fourth option that merges the branch back into the trunk.

In fact, changes between any two repository trees can be defined here for the merging, as long as you know what you are doing. Particularly, the initial repository tree and the final repository tree can be of contiguous revisions, say, revision N-1 and revision N, respectively. In this case, the differences between the initial and the final repository trees can be specified by changeset N, and the merging has a special term called cherrypicking.

The first two options "Merge a range of revisions" and "Reintegrate a branch" as shown in {theme_field_image_as_inline_reference:504} are convenient options that avoid specifying the From and the To manually every time we merge. Behind the scene, Subversion tracks the revisions already merged in a property called svn:mergeinfo (so you would probably see the root project directory has changes). To merge the changes from the trunk of a branch into the branch, use the branch as the current working copy, and choose "Merge a range of revisions",

Fig. 4.  The first option which merges changes from the trunk into the branch.

To reintegrate the branch back into the trunk after the branch is finished, use the trunk as the current working copy, and choose "Reintegrate a branch",

Fig. 5.  The second option which reintegrates the branch.

Branch reintegration means all the changes in the branch is merged into the trunk and the branch should be abandoned or removed. The reason is that after the reintegration, the trunk and the branch are the same, or specifically, the trunk has the changes in the branch, but this is not reflected in the svn:mergeinfo property. The next attempt to merge changes from the trunk into the branch will end up with merging the changes already in the branch. To keep working in the branch, we can either delete and re-create the branch, or mend the svn:mergeinfo property using the last two options shown in Fig. 1. I personally prefer the former, because creating a branch is cheap in Subversion.

Here are some more facts we may need to know about the merging in Subversion:

  1. The differences between an initial repository tree and a final repository tree can also be applied backward to the current working copy which is essentially undoing the changes marked by the differences.
  2. Until Subversion improves, be wary of merging copies and renames from one branch to another.

Comments

Confusing tutorial by Anonymous (not verified)

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

More information about formatting options

To prevent automated spam submissions leave this field empty.