Cauhx Milloy
Cauhx Milloy

Reputation: 81

Merging changes between svn branches

Background

Our server is running subversion 1.8.10. Our clients use 1.8+. We mostly use TortoiseSVN (so I will describe using tortoise terms), version 1.8+.
Our (common) subversion workflow is:

This all works perfectly fine.

The problem

We have run into situations in which, say, BranchA has some changes (e.g. adds some files). It is up to date (from trunk) and going through code review before it gets merged back into the trunk. BranchB is created (from trunk) and would like to get the changes from BranchA in order to build forth from them.
If we MRoR from BranchA to BranchB, we get the changes as we would expect. We can merge BranchA as many times as we like, we can also MRoR from trunk into BranchA or BranchB.. all seems fine.
BranchA can be merged back into trunk (using MTDT), works fine. However, once we MRoR trunk into BranchB again, after BranchA's merge, we get tree conficts. Why is this? SVN is tracking the merge history, it can see BranchA is who created/moved/etc files. If I do the same process, but instead use MTDT to merge from BranchA to BranchB, the outcome is the exact same. This still happens even if BranchB has no changes of its own.

What is the proper way to merge from BranchA into BranchB such that no tree conflicts arise, upon next MRoR from trunk to BranchB, after BranchA has been merged back into trunk?

This sort of thing is easily done in git. I'm sure that there should be a way to get around the tree conflicts.

Thanks for any help!

Upvotes: 0

Views: 1451

Answers (2)

Cauhx Milloy
Cauhx Milloy

Reputation: 81

I've done some testing and have it figured out. I'll go ahead and share how to do this, in case more people out there have the same issue.
To recap:

  • BranchA and BranchB exist (branched from trunk).
  • BranchA has some files added/renamed/moved/deleted/etc.
  • BranchB has merged BranchA into itself (through Merge Range of Revisions (MRoR)).
  • BranchA has MRoR'd from trunk (so it is up to date and ready to be merged).
  • BranchA has been merged (using Merge Two Different Trees (MTDT)) back into trunk.
  • If BranchB tries to get changes from trunk (using MRoR), there will be tree conflicts.

The tree conflicts actually make sense, when you think about it. From BranchB's perspective, it gets some files modified from the merge from BranchA, then again from the merge from trunk. Thus, tree conflict. The issue is that the merge that is coming from the trunk does not let BranchB know that BranchA has been merged into trunk. There are actually two ways to fix this.

Solution:

Method 1 (more complicated method)

  1. After BranchA has been MTDT'd into trunk, do an MRoR from trunk into BranchA. BranchA now contains the history of trunk, post-BranchA MTDT.
  2. Do an MRoR from BranchA into BranchB. BranchB now contains trunk history post-BranchA MTDT.
  3. MRoR from trunk into BranchB. No tree conflicts! YAY!

Method 2 (simpler method)

  1. Any time after BranchA has been merged, do a MTDT from BranchA (@ revision last merged into BranchB) to trunk (@ any revision post-BranchA MTDT -- HEAD will do just fine) into BranchB.
  2. MRoR from trunk into BranchB. No tree conflicts! YAY!

More reasons why Method 2 is better (besides that it's 1 less step).

  • Method 1 requires an extra step (step 1) after a branch is merged (every time), complicating the branch merge process.
  • Similarly, Method 1 requires step 1 to be done in forethought, skipping that step means Method 2 is the only salvation (why not just go with Method 2 in the first place?).
  • If BranchA has been deleted, using Method 1, you have to find the last revision where A existed (to perform step 2). This can prove to be a pain.
  • Finding the correct revision to MTDT from for step 1 in Method 2 is really easy. Just check the history for BranchB, its the last revision BranchA was MRoR'd in.
  • If new changes were made in BranchA between the last MRoR into BranchB and when BranchA was MTDT'd into trunk, Method 2 will account for this and still merge all the necessary content into BranchB.

If it's not made clear, just go with Method 2.
I know that this is a bit of an advanced SVN workflow. But, I hope that this explaination has helped someone else who has had similar issues.

TortoiseSVN merge strategy source: https://tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-dug-merge.html

Upvotes: 1

Lazy Badger
Lazy Badger

Reputation: 97395

  1. You must to own fix weakness and errors in workflow before going deeper:

    • Weakness: For SVN 1.8.* with rather good and smart merge-tracking step 3 can|have to be (any amount of time) just the 'complete' merge (see svn help merge form. 1)
    • Big Error: Merging feature-branch to trunk /child to parent/ MUST NOT BE (and never was) Two-URL-Merge (I even can't imagine how you do it): instead of zillion words I'll recommend re-read " Reintegrate Merge Example" from help again and again
  2. AFAICR, even with correct workflow for "circular" merges (A->B->C->A) mysterious tree-conflicts (before and in TSVN 1.8.11) some time ago (your experience now may differ) and finished with merging branches in Mercurial (that included handwork of replacing WC of SVN-target by content of Working Directory of Mercurial - Mercurial can interact with SVN bidirectionally, but stll can't push own mergesets into SVN-repo) and manual editing of mergeinfo in SVN

Upvotes: 0

Related Questions