Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Subversion Wiki" for 
change notification.

The "SupportedMergeScenarios" page has been changed by JulianFoad:
http://wiki.apache.org/subversion/SupportedMergeScenarios

Comment:
(Manually) import doc from Google docs

New page:
= What Merges Does Svn’s Merge Tracking Support? =
We  need to be able to say, “If you do all your merging like <this>,  it will 
work like you expect.”  So what is <this>?  What are the  supported scenarios, 
limitations and rules, and what can the user expect  within and outside those 
scenarios?

Merging  is a broad term.  We’re talking here about here merging changes that  
have been made on one branch into another branch.  The whole process of  
merging includes several steps which may be manual or automated:

 * selecting a source branch
 * identifying which changes to pull from the source branch
 * applying those changes to a working copy of the target branch
 * resolving any conflicts, both conflicts that Subversion detects and semantic 
conflicts
 * committing the result
 * possibly  other actions such as deleting the source branch if it is finished 
 with, or taking action to “keep it alive” after a reintegrate

This document is concerned primarily with merging in such a way that 
Subversion’s merge ''tracking'' will enable future automatic (''catch-up'' and 
''reintegrate) ''merges to select the correct set of changes.  This answers the 
question, “What ''logical changes''  don't I have on branch B already, that I 
need to pull from branch A to  B?”  A related but different issue is how to 
apply those changes to the  target branch: “For a given physical or logical 
change ‘c1’ that branch A  claims to have an instance of, how do I construct 
from ‘c1’ the best  physical edit that will apply to branch B with the least 
amount of  spurious physical conflict?”

The  information in this document is not intended to repeat the functional  
documentation of the “merge” command itself, but rather to explain the  ways in 
which that command can be used effectively.

=== Identifying Logical Changes vs. Commits ===
To  discuss the nuances of what exactly is tracked in Merge Tracking, we  need 
to think about the difference between a raw change in the  repository (a 
''commit'') and a concept that we can call a ''logical change''.  This 
distinction is ''not'' implemented in Subversion 1.6.

When I commit a change that’s not a merge, we can regard that as introducing a 
new ''logical change''  into my project, on a given branch.  But when I merge 
that change to  another branch and commit the result, that is not creating a 
new logical  change, rather it is the physical representation in that target 
branch  of the same logical change.  (In simple cases the physical change is  
often “the same” but in general it is different, because it is adapted  
automatically or through ''conflict resolution''  to suit that target branch, 
or because in the target branch it is  combined with other logical changes into 
a single commit, or both.)

This is important in an automatic merge, when we want to avoid merging any 
''logical change'' that is already present on the target branch, no matter from 
which intermediate branch it arrived there.

The whole subject of merge tracking is about whether to port the a given 
''logical change'' onto the target branch, or whether that ''logical change''  
has already been put there.  The question is not about the physical  
representation of that change; it doesn’t matter whether the change was  
achieved on the target branch by exactly the same physical edits as it  was in 
the source branch.  The merge algorithm cannot possibly know  whether the 
physical change that was committed (at the time when the  merge info says the 
merge happened) accurately represents the ''logical change''  that is claimed, 
but if it doesn’t (or indeed if it is totally  unrelated), then something has 
gone wrong at a higher level.  As far as ''merge tracking'' is concerned, that 
change was merged.

== Merging Scenarios for Subversion 1.6 ==
Key:

 * A, B, C, …    branches
 * A:3        the change in branch A that was committed as revision 3
 * A ⇒ B        a high-level relationship assumed between branches A and B, in 
the indicated direction
 * A → B        a merge from branch A to branch B

### TODO: Diagrams. This needs to be more visual to be easily understood.
=== General Concepts ===
==== What’s a “Change”? ====
The  unit of change that Subversion tracks is the change that was committed  in 
a specific revision, scoped pathwise to a specific subtree.

==== Tracked Merge ====
 1. When  the “merge” command updates the mergeinfo of the target branch to  
record the merge, the result is the kind of merge that Subversion is  able to 
track.  In this document, “a merge” generally refers to this  kind of merge.
 1. A  tracked merge is transitive.  In merging A:10 from A to B, if A:10 was  
itself a merge that brought in one or more recorded changes from  elsewhere 
(say Z:9), then as well as recording A:10 on B, we also record  Z:9 on B.

==== Non-Tracked Merge ====
 1. You  can use the “merge” command to merge changes in such a way that the  
committed result is not recorded as a merge.  In terms of merge  tracking, 
Subversion sees this commit as an original change, not as a  merge.  This kind 
of merge should be used only in special cases.  ###  WHICH MERGES ARE THESE? 
WHEN ARE THEY APPROPRIATE?  WHEN DO THEY HAPPEN  SILENTLY?

==== Record-Only Merge ====
 1. A  “record-only” merge acts like a normal merge except that it does not  
make edits to the target branch, it only updates the mergeinfo on the  target 
branch as if that merge had happened.  After a ''record-only merge''  has been 
committed, although only the mergeinfo changed in that commit,  the merge 
tracking logic sees that commit as the time when the merge  (the one that is 
now recorded) was performed.  It doesn’t notice that  there is no physical 
change in the commit.  It doesn’t care whether the  physical change was in fact 
merged into this target branch in the past  or will be merged in the future.  
If and when the physical change is  merged as a non-tracked merge, that commit 
will be regarded as an  original change and not as a merge.

==== The Immediate Source Branch ====
 1. Merge tracking only notices what changes have been merged from the 
immediate source branch.  Using automatic (''catch-up'')  merges, say we merged 
A:10 into B as B:13, and A:10 into C as C:14, and  now we are about to merge 
“all unmerged changes” from B to C.  When  considering what to merge from B, we 
only look at what revisions on the  source branch B are recorded as having been 
merged into C, and let’s say  we find all changes from B are recorded there 
except B:13.  Subversion  will try to merge the commit B:13 from B to C, and it 
will conflict, at  least logically and probably physically, because it is just 
an adjusted  version of the original change A:10 which has already been merged 
into C  directly.  This is a limitation of the merge tracking algorithm.

=== The Feature Branch Scenario ===
This  scenario is a way of using merges with a branch that has a limited  
lifetime and is going to be merged back into the branch that it is based  on.  
A typical usage is to develop a new feature or a non-trivial bug  fix in a 
software project.

Suppose  the purpose of branch B is to develop some changes based on branch A.  
 From time to time we will bring all the latest changes from branch A  onto B, 
so that the development branch B is always based on a recent  snapshot of the 
state of branch A.  When finished, we will merge the  changes that were 
developed on branch B into branch A.  At that time, we  may have finished with 
branch B, or we may want to continue with some  further development on it and 
merge that second phase of development to  branch A, and so on, but eventually 
we expect to finish with branch B.

We call this relationship A ⇒ B the ''Feature Branch'' relationship.

 1. Branches  A and B must be ancestrally related.  Usually, B is created as a 
copy  of A, but any history in which the nodes A and B share a common ancestor  
is acceptable.
 1. Merges are performed from and to the root of a branch, unless otherwise 
stated.  (See ''Subtree Merges''.)

==== Catch-Up, aka Sync ====
 1. An  “automatic” merge A → B, at any time, brings B “up to date” with A by  
merging all revisions from A that are not already (recorded as being) in  B, 
into B.  The revisions are not merged individually but in batches,  where each 
batch is as big as possible.

==== Reintegrate ====
 1. Reintegrate B → A, when B is sufficiently up to date with A.
 1. After  a reintegrate, before any further catch-up or re-integrate merges  
between A and B, it is necessary to do a record-only merge from A to B.  See 
the 
[[http://svnbook.red-bean.com/en/1.6/svn-book.html#svn.branchmerge.advanced.reintegratetwice|Keeping
 a Reintegrated Branch Alive]] section in the Book for details.

==== Cherry-Pick ====
 1. A → B.  You can cherry-pick any individual revision or revision range from 
A that is not already recorded on B.
 1. B  → A.  You can cherry-pick any individual revision or revision range  
from B that is not already recorded on A and is not itself the result of  a 
merge from A.  (If it is the result of a merge from A, then ###.)
 1. You  should NOT cherry-pick a change from A to B or from B to A that is  
already recorded on the target branch.  (Subversion attempts the merge  but 
does not record it.)  (### Are we sure?)

==== Multiple Branches ====
 1. The ''Feature Branch'' relationship can be daisy-chained.
  * A ⇒ B, B ⇒ C, C ⇒ D, …

 1. The ''Feature Branch'' relationship can be applied one-to-many.
  * A ⇒ B, A ⇒ B2, A ⇒ B3, …
 1. The ''Feature Branch'' relationship cannot be applied many-to-one.
  * '''NO: '''A ⇒ B, A2 ⇒ B, A3 ⇒ B, …

 1. The ''Feature Branch'' relationship cannot be applied with cycles in the 
graph of relationships.
  * '''NO:''' A ⇒ B, B ⇒ A
  * '''NO:''' A ⇒ B, B ⇒ C, C ⇒ A

 1. The ''Feature Branch'' relationship cannot be applied with multiple paths 
in the graph of relationships.
  * '''NO:''' A ⇒ B, B ⇒ C, A ⇒ C
  * '''NO:''' A ⇒ B, A ⇒ C, B ⇒ D, C ⇒ D

==== Reverse Merge ====
 1. A  → B.  You can cherry-pick A → B, the reverse of a change “c1” on A that  
was previously merged (and recorded as merged) to B.  Subversion  records that 
the change is no longer present on B, just as if that  change had not 
previously been merged from A to B, and so “c1” is  eligible for being included 
in a catch-up merge again.
 1. A  → A.  In any branch A you can reverse cherry-pick a change “c1” from  
A’s own history to undo that change.  If the change “c1” was an original  
change in A, this is recorded as a manual edit and is not tracked as a  merge.  
If the change “c1” was a merge (say change “c0” from branch Z)  into A, or 
included such a merge, ### ? that’s fine too, as long as “c0”  is currently 
recorded on A.  Subversion records that the change is no  longer present on A, 
just as if that change had not previously been  merged, and so “c1” is eligible 
for being included in a catch-up merge  again.  But if “c0” was not currently 
recorded on A (for example, if it  already had been reverse-merged once and not 
subsequently  forward-merged), that is not valid; Subversion will perform but 
not  record the merge.

==== Subtree Merges ====
 1. ### ?

=== The Release Branch Scenario ===
In  this scenario, a branch is expected to have occasional edits,  occasional 
cherry-pick merges to and/or from the branch it’s based on,  and there is no 
special merging to be done at its end of life. The set of rules is much simpler 
than for the release branch scenario.

==== Multiple Branches ====
### How do A ⇒ B feature branch relationships connect with C ⇒ D release branch 
relationships?
==== Cherry-Pick ====
 1. A → B.  You can cherry-pick any individual revision or revision range from 
A that is not already recorded on B.
 1. B → A.  You can cherry-pick any individual revision or revision range from 
B that is not already recorded on A.
 1. You  should NOT cherry-pick a change from A to B or from B to A that is  
already recorded on the target branch.  (Subversion attempts the merge  but 
does not record it.)

Reply via email to