See "Keeping a Reintegrated Branch Alive" in the Svn 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 r50 but not r40.

Ways to make it easier

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

Complex Use Case

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

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 2012-01-18 12:46:19 by JulianFoad)