The section on keeping a reintegrated branch alive became obsolete with the release of Subversion 1.8.


Keeping a Reintegrated Branch Alive

A discussion on ways to improve the user experience when trying to keep using a branch after reintegrating it. This was a problem from Subversion 1.5 through Subversion 1.7. See "Keeping a Reintegrated Branch Alive" in the Subversion 1.6 Book here: http://svnbook.red-bean.com/en/1.6/svn-book.html#svn.branchmerge.advanced.reintegratetwice.

Simple Use Case

Here's a diagram showing a typical feature-branch work flow and the step we want to eliminate.

Rev

A

B

Commit

r10

X

r20

X

New branch B from A

r30

X

Modify B

r40

M

Reintegrate B to A

r45

R

Keep-alive record-only merge A@40 to B

r50

X

More work in A

r60

M

Sync merge A to B

The sync merge r60 should "take" the change r50 from A, but not r40. Subversion client versions 1.5 through 1.7 don't merge correctly at r60 without extra help such as that provided by the r45 commit.

Ways to make it easier

(in order from easiest to implement to best for the user):

Subversion 1.8 implements a solution superior to any of the above. The enhancement is announced in the 1.8 release notes and some design notes are in the Symmetric Merge Wiki page.


Complex Merging

Complex Merge Use Case

In the final sync merge in this more general use case, the interesting question is what to do with r11.

(This question is based on the premise that the merge from A to A_COPY will be executed by selecting a set of revisions along the direct history of branch A, and merging them to branch A_COPY. This is what the merge algorithm does in Subversion v1.5 through at least v1.8 (except when reintegrating). A different merge algorithm might be needed to handle this scenario well.)

A@1---r4---r5---r6---r7----------------r11----------->
 |\                                     ^          |
 | \                                    |          |
 |  \                              reintegrate     |
 |   V                                  |          |
 |   A_COPY_2-----------------r9---r10---          |
 |                            ^                sync merge
 |                           /                     |
 |                  cherry-pick merge of r8        |
 V                         /                       V
 A_COPY-------------------r8------------------------->

We can see that part of r11 is "new" and should be merged (the part that came from r10), but another part of r11 is a change we already have (the part that came from r8). What are the options?

  1. Try to merge r11 into A_COPY (and record it as merged), accepting that (in principle) it will conflict.
  2. Don't merge r11 into A_COPY (and don't record it).
  3. Instead of taking r11 as a whole change, find its constituent parts and merge the required parts. Then record r11 as merged.
  4. Stop and report the problem.

Option (1) is the current (<=1.7) behaviour. Merging r11 will (in general) produce conflicts because the part of the change that originated as r8 will be re-played onto A_COPY which already has r8. Some of the conflicts might be "physical" conflicts, detected and reported by Subversion, while others might be automatically resolved by Subversion, while still others might be logical conflicts that cannot be detected automatically. Because we know that the merge will confilct (and can determine it algorithmically), we should at least display a diagnostic message that gives details of which change(s) being merged include some changes that are already present.

Option (2) leaves the user to decide whether and how to fill in the missing bits. Like option (1) we should at least display a diagnostic message that gives details. A disadvantage is that the revisions from the source branch end up being merged out of order: the current merge will proceed with the later revisions, and then if the user wants to merge the relevant parts of the skipped revision those parts will be merged later.

Option (3) could be done in several different ways. Examples:

The best way to perform this partial merge would depend on the relationships between the branches, such as how similar each one is to each other one. There is no single Right Way, and there is no way to perform such a merge that would never produce conflicts. Designing a partial-merge algorithm would advance the merge tracking capability into a significantly more sophisticated model.

Option (3) is too complex and so is not under consideration here.

Option (4) has the advantage that the user can take action such as performing other merges (especially onto the source or target branch of the interrupted merge) before continuing. This may be better than (2) because the source revisions would be merged in order.

I would propose that Subversion give users the ability to specify in advance or interactively what action to take when encountering a partially-merged revision. The backward-compatible default would be option (1) plus a diagnostic message. The options would be (1), (2) and (4).

KeepingReintegratedBranchAlive (last edited 2013-09-03 09:13:11 by JulianFoad)