There are two types of merges in Subversion:
- Merging Three Points
- Point-to-point mergers (reintegration mergers)
Suppose you are working on a trunk and you have a specific function that must be performed. You create a Feature A. branch. When you work on this feature, you want the work you do on the trunk to be included in feature A so that you can keep up with what everyone else is doing. Subversion will use three-point merging.
Subversion will consider the difference between a connection bus and a branch. Function A from the point at which the branch occurred. The most recent common ancestor. Then it takes into account all changes in function A that were made (which you do not want to touch), as well as changes in the code executed on the trunk.
Subversion will then merge the changes in the tube without overwriting the changes made on the branch. The standard merge procedure, and Subversion does it quite well.
Where is svn:mergeinfo ? You do not want to merge the same changes twice, so Subversion tracks changes using the svn:mergeinfo . If Subversion sees that the chest change from Revision 5 has already been merged, it will not repeat that change. This is very good with that.
Now you have finished your function and want these changes to be merged back into the trunk. You make one last connecting line to merge the branches, commit these changes and now merge from the Feature branch to trunk.
This is a bit of a problem. We tracked what we combined from trunk to Feature branches via svn:mergeinfo . However, since we did not merge with the Feature branch in trunk, there is no svn:mergeinfo . If we try to do the usual three-point merge from the Feature branch to trunk, the trunk assumes that all changes to the Feature branch should be merged back into the trunk. However, many of these features are in fact changes to the trunks that have been combined.
Verily, at the moment we want to do a two-point merge. We want both the connecting line and the Feature branch to match exactly after the merge. In the end, we regularly merge the trunk into Feature branches. What we want to do is to include these features in the trunk. Thus, the connecting line will be the same as the function branch.
Before Subversion 1.8, you will need to force merge reintegration by running svn merge --reintegration . Subversion will now review the merge history and find out when the merge of reintegration should be performed.
Now here is the hard part. Take a look at the revision numbers. It will be very, very important!
- Revision 10 . I introduced the final changes to Trunk, and I need to merge them into the Feature branch.
- Version 11 . I am merging a connector line into Feature branches.
svn:mergeinfo will show that all trunks from version 1 to version 10 are in the Feature branch. Since the last change to trunk is editor 10, this makes sense. - Revision 12 . I merge version 11 of the Feature branch into trunk. This is a reintegration union. After that, what is on the Feature branch and what is in the trunk should fully agree.
Now, here is the kicker!
- Revision 13 . I make another change in the trunk.
Now I want to merge this into my Feature branch (creating Edition 14). So what does svn:mergeinfo in function branches? It says that the trunk from version 1 to version 10 has been merged with the Feature branch. However, there were no Revision 12 and Revision 13 of the chest. Therefore, Subversion will want to merge version 12 and version 13 back into the Feature branch.
But wait a second!
Version 12 on the trunk was my combination of all the changes in my Feature branch back to the trunk! That is, version 12 already contains all the changes that I made to the Feature branch. If I merged Revision 12 into my Feature branch, I will say that all these changes in Revision 12 on trunk (which were really made to the Feature branch and merged into trunk) should be merged into the function branch. But these changes have also been made to the Feature branch. Can you say merge conflict? I knew you could!
There are two ways to deal with this:
- Recommended method : After you reintegrate your function branch back into the trunk, delete the branch. Shut the. Never use it again. Do not touch! This is not as bad as it seems. After the merger of reintegration, your trunk and the branch of this function will coincide. Removing and re-creating a branch from the trunk is not so bad.
- A complicated way that works . We need to trick Subversion into believing that Revision # 12 (or merge reintegration changes) has already been merged into our Feature branch. We could work with the
svn:mergeinfo . And I use it. Where he says trunk:1-11 , I would manually change it to trunk:1-12 .
This is complicated, but too complicated and risky, because Subversion already gives you a way to manipulate svn:mergeinfo without manually changing it.
He called the record only a merger.
$ svn co svn://branches/feature_a $ cd feature_a $ svn merge --record-only -c 12 svn://trunk $ svn commit -m "Adding in the reintegration merge back into the feature branch."
This changes svn:mergeinfo to function branches without affecting the actual contents of the files. No real merge is done, but Subversion now knows that version 12 of the trunk is already in the Feature branch. After that, you can reuse the function branch.
Now take a look at your diagram: when you merged Branch B into Branch A, you merged all changes from B to and svn:mergeinfo tracked this. When you merge Branch B back into Branch A, you already have all the changes from Branch B to Branch A, and you do not want these changes to be returned to branch B. You should use a reintegration merge:
$ cd $branch_a_working_dir $ svn merge $REPO/branches/B $ svn commit -m "Rev 7: All of my changes on Branch B are now in A" $ vi d.txt $ svn add d.txt $ svn commit -m"Rev 8: I added d.txt" $ cd $branch_b_working_dir $ svn merge --reintegrate svn://branch/A
Now, if we want to continue using branch A for further changes:
$ cd $branch_a_working_dir $ svn merge -c 9 --record-only $REPO/branches/b $ svn commit -m"I've reactivated Branch A and can make further changes"
Hope this explains a little how svn:mergeinfo , why you should know if you are using a regular three-point merge against a two-point merge reintegration, and how to activate the branch after you have done the merge reintegration.
As long as you keep this in mind, Subversion merging works very well.