When is the reintegrate option really necessary?
Asked Answered
F

4

18

If you always synchronise a feature branch before you merge it back. Why do you really have to use the --reintegrate option?

The Subversion book says:

When merging your branch back to the trunk, however, the underlying mathematics is quite different. Your feature branch is now a mishmosh of both duplicated trunk changes and private branch changes, so there's no simple contiguous range of revisions to copy over. By specifying the --reintegrate option, you're asking Subversion to carefully replicate only those changes unique to your branch. (And in fact, it does this by comparing the latest trunk tree with the latest branch tree: the resulting difference is exactly your branch changes!)

So the --reintegrate option only merges the changes that are unique to the feature branch. But if you always synchronise before merge (which is a recommended practice, in order to deal with any conflicts on the feature branch), then the only changes between the branches are the changes that are unique to the feature branch, right? And if Subversion tries to merge code that is already on the target branch, it will just do nothing, right?

In a blog post, Mark Phippard writes:

If we include those synched revisions, then we merge back changes that already exist in trunk. This yields unnecessary and confusing conflicts.

Is there an example of when dropping reintegrate gives me unnecessary conflicts?

Fume answered 5/11, 2009 at 13:19 Comment(0)
Q
10

Let me explain when --reintegrate is absolutely necessary.

Consider the following use case.

  1. you have project p1 under p1/trunk. The project has a file, readme.txt, with one line "line1"<
  2. Create a new branch, p1/branches/br1
  3. Stay in trunk. Add line "line2" to readme.txt and commit it to trunk
  4. Switch to the p1/branches/br1 branch. Update to HEAD.
  5. Merge from trunk to this branch (to pick up trunk changes).
  6. You should have line1 and line2 in readme.txt
  7. Commit merge the result to p1/branches/br1 branch
  8. Switch to trunk. Update to HEAD.
  9. Merge from p1/branches/br1 to trunk.
    1. You'll see line1, line2 and line2 in readme.txt. So, you have "line2" two times which is incorrect. SVN does not show any conflicts. So, it is very dangerous because merge performed with no errors and you are under impression that everything is fine.

The solution here is that the step 9 merge should be done using the --reintegrate option. The reintegrate option tells SVN to compare br1 with trunk and apply only br1 changes to trunk. In this particular case we have not done any changes in br1. The result in trunk should be two lines "line1" and "line2".

Another useful remark. Branch p1/branches/br1 should not be used for development after step 9 anymore. If you want to continue development in branches, create a new branch, for example, p1/branches/br2. Another merge from trunk to p1/branches/br1 causes lots of conflicts.

Qualitative answered 15/8, 2011 at 22:2 Comment(2)
I've just done this test using SVN 1.7.0 and I don't see this happening. What I see instead is SVN automatically filtering out changesets that already exist in related branches irrespective of the direction of the merge (trunk to branch or branch to trunk). Has SVN's behaviour in this area changed in a way that is not reflected in the documentation?Luciferin
I've also done your test with Netbeans 7.3.1 (which should use SVN 1.7), my SVN server is 1.6.17 and I don't have any problems with duplicate rows.Juggle
S
3

It is never necessary to use --reintegrate; it's a convenience. If your most recent merge from trunk to feature-branch merged all of the changes that occurred in trunk since you branched up to revision rev, then you could use the following command.

svn merge url://trunk@rev url://feature-branch .

Note that this command would be run in the root of an up-to-date working copy of trunk with no outstanding changes to be committed.

Let me expand my answer to more directly answer the question "Is there an example of when dropping reintegrate gives me unnecessary conflicts?"

Here's what the article means by "If we include those synched revisions, then we merge back changes that already exist in trunk. This yields unnecessary and confusing conflicts."

Including the synched revisions would look like this:

svn merge -r N:HEAD url://feature-branch .

Where . is a clean working copy of trunk and N is the revision that feature-branch was created from trunk. That merge command merges all of the changes committed to the feature-branch since it was branched, including those changes that were merged from trunk after the feature-branch was created. That means changes already made to trunk would be included in the merge above. You'd be telling Subversion to apply changes to trunk that actually originated in trunk, which results in conflicts.

Sinasinai answered 5/11, 2009 at 17:57 Comment(3)
Well, that's what I don't understand. Why would changes that exist in both the branch and trunk lead to conflicts, if those changes are identical?Fume
@Tor, you would see a conflict if you had made any changes in the branch to the modified code. In other words, those changes may no longer be identical. Imagine you added 5 lines on the trunk, synced to the branch, and then modified them on the branch. A merge would then show a conflict: 5 lines on the trunk vs 5 different lines on the branch. But if you used --reintegrate, it would simply notice the difference on the branch and merge that without prompting.Caseate
Does this mean that when merging without reintegrate, say "svn merge -r 1:100 url://feature-branch ." will find all changes made to url://feature-branch from rev 1 to rev 100, and apply each of them to . one by one. While with reintegrate, SVN will just compare the difference between rev 100 and rev 1, and treat these difference as changes, then apply to . ?Corse
O
1

I think that Mark means it avoids comparing two files which have been modified, one to reintegrate from the branch and its corresponding file in the trunk, when both have been synchronized (and not just changed locally in their respective branch).

Let's assume we have trunk/a.c and branches/dev/a.c, with trunk/a.c modified at some point and re-integrated in the branch later with a merge. As you pointed out, it's a good practice to do that before putting everything back to the trunk.

So the next step would be that merging back to the trunk, where a.c are "different" on both sides since they have changed at both locations. Without the option there will be an unnecessary comparison, wheras the --reintegrate will make SVN see the change was not just local.

Oxidation answered 5/11, 2009 at 13:40 Comment(1)
Yes, I can understand the "unnecessary comparison". But not the "unnecessary conflict," which is what the documentation is talking about.Fume
I
0

It’s never necessary to use --reintegrate — it’s simply an alias. If you have a working copy of trunk, then

svn merge --reintegrate url://feature-branch workingcopy

is the same as

svn merge url://trunk url://feature-branch workingcopy

You can use whichever one you’re more comfortable with.

Icao answered 5/11, 2009 at 16:5 Comment(6)
Hmm. I'm not 100% sure, but I think you're mistaken on this one. At least the svnbook gives quite a different picture of it. svnbook.red-bean.com/nightly/en/…Independency
@Michael: Are you really sure of that? In the SVN documentation it's pretty clear the behaviour is different, do you mean it detects that automatically from specifying the two URL's?Oxidation
That’s according to the link specified in the OP. “The new reintegrate option is a shorthanded version of the 2-URL merge ... In other words, reintegrate is just a new syntax plus some safety checks.” I apologize, but I don’t have firsthand experience with this option.Icao
Reintegrating a Branch (1.6).Trig
Which states: When merging your branch back to the trunk, however, the underlying mathematics is quite different. Your feature branch is now a mishmash of both duplicated trunk changes and private branch changes, so there's no simple contiguous range of revisions to copy over. By specifying the --reintegrate option, you're asking Subversion to carefully replicate only those changes unique to your branch. (And in fact, it does this by comparing the latest trunk tree with the latest branch tree: the resulting difference is exactly your branch changes!)Trig
Also applies as early as 1.5Trig

© 2022 - 2024 — McMap. All rights reserved.