Which SVN uses actual use of mergeinfo?

I have long heard about svn merge-conflict issues.

I was pleased, I thought when I found out that svn a couple of releases ago implemented a function called mergeinfo . It seemed that his introduction would allow svn to have enough information to solve the merge problems when they appeared. Until I got into the following situation:

enter image description here

Example scenario above:

 SVN=${SVN:-svn} SVNADMIN=${SVNAMDIN:-svnadmin} rm -rf repo wc $SVNADMIN create repo $SVN co file://$PWD/repo wc cd wc # r1 $SVN mkdir trunk branches $SVN ci -m 'structure' $SVN up # r2 echo 2 > trunk/t.txt $SVN add trunk/t.txt $SVN ci -m 'add t.txt' $SVN up # r3 $SVN cp trunk branches/A $SVN ci -m 'create branch A' $SVN up # r4 echo 4 > branches/A/a.txt $SVN add branches/A/a.txt $SVN ci -m 'add a.txt' $SVN up # r5 $SVN cp trunk branches/B $SVN ci -m 'create branch B' $SVN up # r6 echo 6 > branches/B/b.txt $SVN add branches/B/b.txt $SVN ci -m 'add b.txt' $SVN up # r7 $SVN merge ^/branches/B branches/A $SVN ci -m 'merge branch B into A' $SVN up # r8 echo 8 > branches/A/d.txt $SVN add branches/A/d.txt $SVN ci -m 'add d.txt' $SVN up # r9 $SVN merge ^/branches/A branches/B 

If svn keeps a history of where each branch comes from, why can't it understand that b.txt left untouched by @ branch A ?

if he can't figure it out, what is the actual use of svn from mergeinfo ?

If svn is unable to cope with this problem, would it not be possible to create a tool to help me (namely, automatically resolving such problems without problems) on this front? I would suggest maybe it already exists?

thanks

+7
version-control merge svn
source share
3 answers

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 # Note this is a REINTEGRATION merge! $ svn commit -m"Rev 9: I've reintegrated Branch A into Branch B 

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.

+12
source share

David W.'s answer is pretty good, but I'm going to provide my own answer that answers this question with a more modern approach. What David tells you is true, and it is helpful to understand his answer when reading my answer, so you should read it first if you have not already done so. My answer provides a more up-to-date understanding of the problem and solutions to the problems that David points to.

So, first of all, the simple answer is that the situation you represent works fine if you are using Subversion 1.8. The sample script that I added to the question has no conflict when starting using Subversion 1.8. To get this functionality, only the client needs to be updated.

The longer answer here is that in older versions of Subversion you need to know when to use the weakly named option --reintegrate (this shows 1.8 for you). Despite the fact that the name --reintegrate is not only intended to reintegrate the branch back into your trunk.

One of the recurring problems that people face is that they use function branches - that they want to merge the function branch back into their trunk and then continue to use the branch. According to David, in the past there were two methods of dealing with this. First remove the branch, and then make it fresh. Secondly, the record is only merging. Julian Fod, one of my Subversion fellow developers, when working in 1.8, realized that neither of these two methods was needed. He talked about this in his presentation about the merger at the Subversion Live 2012 conference . The slides for his presentation are available on the Internet here (note that this is a PDF file for all the slides for the conference, therefore it is not quite tiny), some of these problems begin on page 123.

To summarize his presentation, a typical workflow of function branches is to create a branch from the outside. Make a commit to the branches of your function and periodically step from the trunk to the branches of your function to synchronize with what's on the trunk, for example. svn merge ^/trunk $BRANCH_WC . Then, when you are ready to merge back into the torso, you do svn merge --reintegrate ^/branches/myfeature $TRUNK_WC . Now you are to such an extent that the traditional wisdom was that you had to delete your function branch or record only by merging. Instead, Julian discovered that you can just keep using the branch if you follow these rules.

  • Each time you merge in the same direction as the last merge between two branches, you do NOT use the --reintegrate option. Treat branch creation as a merge from this creating location.

  • Each time you change directions that you merge between two branches, use --reintegrate for this merge.

In your particular case, you change the direction with which you merged. r7 merges from branch B to branch A. r9 merges from branch A to branch B. Therefore, when you go to merge r9, you need to use --reintegrate . This logic is exactly what Subversion does for you with 1.8.

Finally, I do not recommend merging between the branches you are doing here. Many simple cases, like what you do here, will work well. However, if, for example, you split the file ( svn cp file file2 , delete part of file1 and the other part from file2), then you will encounter problems when trying to merge the last of the two function branches back to the trunk (assuming that you merged the separation into two branches of the sister). It is best to limit the union between two branches (child and parent). You can disconnect branches from other branches and return to parents before moving to the parent parent and so on, and everything will be all right. We would like this to work properly in the future, but the situation is that now the situation is at 1.8 (much better than we were in the past, but not as good as we would like).

+7
source share

You misunderstood the meaning and use of mergeinfo - it only contains (for this node) merged changes and source merges so as not to merge the revision twice, nothing about the content

0
source share

All Articles