I don't believe version 1.8 solves the branch reuse problem. The problem has to do with the revision numbering and how Subversion tracks what revision is where.
Let's start with Revision 100. I have done changes on trunk, and I want to merge all of these changes into my branch. I do a standard merge and create Revision 101 (on my branch). On my branch, the svn:mergeinfo
shows that all changes on trunk up to and including revision 100 are now on my branch. So far, my last trunk revision is Revision 100. All is fine and good.
Now, I want to reintegrate my changes back into trunk. I do a reintegration merge which does a two-way merge, so after the merge, my trunk will now look like my branch. This is revision 102, and it's on my trunk. So far, I've merged Revision 100 onto my branch, Revision 101 is not on my trunk, but I now have Revision 102 on my trunk.
I now make another change on trunk. This is revision 103. I decide that this is also needed on my branch.
My branch says that all revisions on trunk up to Revision 100 have been merged onto my branch. So far, so good. I now will do another merge, and there are now two new revisions on my trunk: Revision 102 and Revision 103. According to svn:mergeinfo
, the changes in both of these revisions need to be merged into my branch.
But wait! Revision 102 was the reintegration merge from my branch to trunk. This information is already on the branch. Merging Revision 102 again will mess up my branch. I'll probably get a ton of merge conflicts.
There's no real way for Subversion to detect this issue. There are two ways of solving this problem:
- Never ever reuse the branch or
- Do a
svn merge --record-only -r102
to record that revision 102 is already on the branch. This makes no changes in the file (except for the value of the property svn:mergeinfo
).
If you did #2, you can now merge your changes from trunk back onto the branch because, svn:mergeinfo
will state that all changes on your trunk up to and including Revision 102 are on your branch. Only the changes in Revision 103 needs to be put onto your branch.
So what is your issue?
Subversion now can detect whether you need to do a regular (three way) merge and a reintegration (two-way) merge. You no longer need to use the --reintegration
parameter.
However, you cannot do a reintegration merge unless you've previously merged all of the changes that are on the trunk into your branch.
Let's say you have merged all revisions from trunk onto your branch except for revision 95. Your trunk contains the change in Revision 95, but your branch doesn't have this change. If I do my reintegration merge, I am doing a two-way merge. I am going to make my trunk match my branch -- my branch which doesn't have the change you did in Revision 95.
If I merge my branch into my trunk, I lose the changes in Revision 95 I made on my trunk.
You do not want that to happen. Therefore, Subversion will warn you if you're doing a reintegration merge, but haven't merged all of your trunk changes back into the branch.
Let's look at your message again:
svn: E195016: Reintegrate can only be used if revisions 8 through 11 were previously merged from svn://svn2010/practice/branches/featurebranch2 to the reintegrate source, but this is not the case:
trunk/file1.txt
Missing ranges: /trunk/file1.txt:9
This is telling you that you want to reintegrate all of your changes up to Revision 11 back into your trunk. However, Revision #9 was never merged onto the branch. If you do a reintegration merge, you will lose this change on your trunk.
In order to proceed, you either need to use --force
(a bad idea), or do another merge from trunk back into branch to get the changes in Revision 9 onto your branch.
Once this is done, you can do your branch-to-trunk merge.
I hope this clarifies the situation.
Unix Version of your script
Here's my version of the script. It was more or less translated from Windows Batch to Bash shell. The main difference is:
- Step 9.5: I find the last change on trunk. This is the revision you have to record on your feature branch in order to reuse it.
- Step 10: I use
--record-only
on the feature branch with the -c
because you have to in order to reuse your feature branch. It works just fine in Subversion 1.8. This works just fine on both Mac OS X Mavericks and RHEL 6. I haven't tried it on 6.5.
The main difference between SVN 1.7 and SVN 1.8 in this scenario is that SVN 1.7 would have done the merge without any warning while SVN 1.8 attempts to warn you about the issue. I'm not sure why Revision 9 was reported. It was the last merge from this branch onto trunk, it seems the message should have stated Revision 11 which is the revision that was reintegrated. I take that the error is due to engineering language skills more than any sort of error.
By the way, instead of running:
svn merge --record-only -c$last_changed $URL/trunk featurebranch2
If I ran this:
svn merge --force $URL/trunk featurebranch2
The merge happens just as it would in Subversion 1.7. I this case, the merge happens correctly, but it's because you didn't change the files on trunk or the branch before you did the final merge. It was just luck
#! /bin/bash
# svnscript.sh
#
# ECHO STEP 0: Create a repository
echo "Create Repository"
[[ -d "repo" ]] && rm -rf repo
[[ -d "trunk" ]] && rm -rf trunk
[[ -d "featurebranch1" ]] && rm -rf featurebranch1
[[ -d "featurebranch2" ]] && rm -rf featurebranch2
svnadmin create repo --compatible-version 1.8
URL="file://$PWD/repo"
echo "URL=$URL"
########################################################################
# STEP 1: Create a trunk with 2 files
########################################################################
echo "Step 1: Create a trunk with 2 files"
svn mkdir -m"Create trunk" $URL/trunk
svn checkout $URL/trunk
echo Original file contents created in the trunk. > trunk/file1.txt
echo Original file contents created in the trunk. > trunk/file2.txt
svn add trunk/file1.txt
svn add trunk/file2.txt
svn -m "Added 2 files" commit trunk
########################################################################
# STEP 2: Create co copy (feature branch) from the trunk
########################################################################
echo "STEP 2: Create a feature branch from the trunk"
svn mkdir -m "Create branches dir" $URL/branches
svn copy -m "Create featurebranch1" $URL/trunk $URL/branches/featurebranch1
########################################################################
# STEP 3: Modify both files in the feature branch
########################################################################
echo "STEP 3: Modify both files in the feature branch"
svn checkout $URL/branches/featurebranch1
echo "Additional file contents created in featurebranch1." >> featurebranch1/file1.txt
echo "Additional file contents created in featurebranch1." >> featurebranch1/file2.txt
svn -m "Modified 2 files in featurebranch1" commit featurebranch1
########################################################################
# STEP 4: Merge both files from featurebranch1 to the trunk
########################################################################
echo "STEP 4: Merge both files from featurebranch1 to the trunk to "
echo " create local mergeinfo on both files"
svn update trunk
svn merge $URL/branches/featurebranch1/file1.txt trunk/file1.txt
svn merge $URL/branches/featurebranch1/file2.txt trunk/file2.txt
svn -m "Merged 2 files from featurebranch1 to trunk" commit trunk
########################################################################
# STEP 5: Delete Feature1 branch: No longer needed
########################################################################
echo "STEP 5: Delete featurebranch2, we only needed it for the"
echo " initial setup"
svn delete -m "Delete featurebranch1" $URL/branches/featurebranch1
########################################################################
# STEP 6: This is the start of the problematic scenario
########################################################################
echo "STEP 6: This is the start of the problematic scenario"
echo " Create a featurebranch2"
svn copy -m "Create featurebranch2" $URL/trunk $URL/branches/featurebranch2
svn checkout $URL/branches/featurebranch2
########################################################################
# STEP 7: Modify the contents of file1.txt. in trunk
########################################################################
echo "STEP 7: Modify the contents of file1.txt in the trunk and leave"
echo " the contents of file2.txt unchanged (this is important)"
echo "Additional file contents created in the trunk." >> trunk/file1.txt
svn -m "Modified file1.txt in the trunk" commit trunk
########################################################################
# STEP 8:Sync merge the trunk to featurebranch2
########################################################################
echo "STEP 8: Sync merge the trunk to featurebranch2"
svn update featurebranch2
svn merge $URL/trunk featurebranch2
svn -m "Sync merged the trunk into featurebranch2" commit featurebranch2
########################################################################
# STEP 9: Reintegrate featurebranch2 back into the trunk
########################################################################
echo "STEP 9: Reintegrate featurebranch2 back into the trunk"
svn update trunk
svn merge $URL/branches/featurebranch2 trunk
svn -m "Reintegrated featurebranch2 back into the trunk" commit trunk
########################################################################
# STEP 9.5: Get the last change info on Trunk
########################################################################
svn update trunk
last_changed=$(svn info $URL/trunk | sed -n '/Last Changed Rev/s/.*: //p')
########################################################################
# STEP 10: Try to reuse featurebranch2 after it was reintegrated
# This time, we'll use the --record-only with the change on trunk
########################################################################
echo " STEP 10: Try to reuse featurebranch2 after it was reintegrated"
echo " Sync merge it from the trunk. THIS FAILS with SVN 1.8 "
svn update featurebranch2
svn merge --record-only -c$last_changed $URL/trunk featurebranch2
svn commit -m"It works on MY machine!" featurebranch2