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?action=diff&rev1=14&rev2=15

Comment:
Wording improvements

  ==== and Why Conflict Resolution is Part of Merging ====
  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''.
  
- Whenever I commit a change that’s not a merge, we can regard that commit 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 commit 
is not creating a new logical  change, rather it is creating a new physical 
representation (in the target branch)  of ''the same logical change''. In 
simple cases the physical change often looks “the same” when viewed as a diff, 
perhaps with the exception of line numbers and surrounding context lines. In 
trivial cases, such as a catch-up merge to a target branch that does not yet 
contain any modifications of its own, the physical change is identical. In 
general, however, the physical change on the target branch is necessarily 
different from the source branch change. It is adapted automatically (by 
Subversion or the user's configured 3-way merge tool) and/or manually (through 
''conflict resolution''),  to fit the current state of the target branch. 
([[#Note_2|2]])
+ {{{#!wiki note
+ This subsection describes a theoretical basis for understanding merging.  It 
does not directly describe the behaviour of Subversion's merge tracking at the 
moment.
+ }}}
  
- The distinction between a ''commit'' and a ''logical change'' 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.
+ Whenever I commit a change that’s not a merge, we can regard that commit 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 commit 
is not creating a new logical  change, rather it is creating a new physical 
representation (in the target branch)  of ''the same logical change''. In 
simple cases the physical change often looks “the same” when viewed as a diff, 
perhaps with the exception of line numbers and surrounding context lines. In 
trivial cases, such as a catch-up merge to a target branch that does not yet 
contain any modifications of its own, the physical change is identical. In 
general, however, the physical change on the target branch is necessarily 
different from the source branch change. It is adapted automatically (by 
Subversion or the user's configured 3-way merge tool) and/or manually (through 
''conflict resolution''),  to fit the current state of the target branch. 
([[#Note_2|2]]) ([[#Note_3|3]])
  
- 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, since we don't expect the change on the target branch to 
consist of exactly the same physical edits as it did in the source branch.
+ The distinction between a ''commit'' and a ''logical change'' is important 
for merge tracking.  The whole purpose of merge tracking is to decide whether 
to select a given change on the source branch to be merged onto the target 
branch or whether that logical change has already been put there.  The question 
is about whether ''the same logical change'' is already present on the target 
branch.  The question is not about the physical representation of that change, 
since we don't expect the change on the target branch to consist of exactly the 
same physical edits as it did in the source branch.  Nor do we care whether 
whether the change arrived on the target branch by being merged directly from 
the original revision on the original branch A where that logical change was 
first committed to the repository, or whether it arrived in the middle of a 
merge of a batch of changes from branch C, if branch C received the change in a 
merge from branch B which was merged from branch A.  When we want to merge 
"everything" from branch C to branch A, the merge tracking needs to be able to 
consider the possible changes to be merged from branch C and realize that the 
change at revision 130 on branch C is just a merge from branch B which was 
itself a merge from branch A, and thus we must not try to merge revision 130 of 
C to A because we already have the logical equivalents of that change in branch 
A.
  
- {{{#!wiki note
- The merge algorithm cannot possibly "know" by inspection  whether the 
physical change that was committed as a merge is a faithful representation the 
set of ''logical changes''  that the mergeinfo claims it is.   As far as 
''merge tracking'' is concerned, if the mergeinfo says a given ''logical 
change'' was merged, it was merged. The user interfaces should assist the user 
in understanding this.
- 
- The UI may also provide the user with a way to tell Subversion that he/she 
has merged a given logical change into the WC manually (not using the 'merge' 
command), or has merged a change into the WC and then decided to remove it 
before committing and not record it as merged.  The command-line interface for 
these is "svn merge --record-only".
- }}}
- ### NEW text to be edited in:
  In order to make sense of this, I consider the definition of a tracked change 
to be:
  
-  * The unit of change tracked is a logical change to the versioned  tree, 
which was originally committed to one branch, which has a meaning  or purpose 
that remains the same no matter which branch it ends up being  merged onto.
+  * The unit of change tracked is a logical change to the versioned tree, 
which was originally committed to one branch, which has a meaning or purpose 
that remains the same no matter which branch it ends up being merged onto.
  
  The meaning or purpose of a logical change is typically described in the  log 
message of the original commit.  A realistic example is "Delete  function foo() 
and change all callers to use the similar function bar()  instead".
  
  Merge tracking should treat every original commit as that kind of  "logical 
change".  This definition doesn't presuppose that every commit  is *actually* 
relevant to every other branch in your project.  If and  when you want to merge 
this change to a branch that doesn't have a  function foo() and code that calls 
it, then clearly you have logical  conflict between the states of the two 
branches.  This change and almost  certainly a series of other changes will 
either be inapplicable or will  need some minor or major editing to resolve the 
logical conflict to  make them applicable.  Resolving such conflicts, including 
omitting  changes by hand that the system says logically should be merged, is a 
 normal and expected part of merging.
  
- The physical manifestation of a given logical change will in general  differ 
on different branches.  In simple cases the physical  manifestation will be 
similar: for example, the default "svn diff"  output may be the same except for 
the line numbers.  In a slightly less  trivial example perhaps the context 
lines will also be different.  And  getting bit more involved, perhaps the 
removed "-" lines will be  slightly different but the added "+" lines will be 
just the same.  Or  perhaps the diff will be just the same except in a renamed 
file.  (Side  note: Although what we mean by the physical manifestation is kind 
of  obvious, in  fact it is subtly hard to pin down, because it depends 
entirely how you  represent the physical change.  If we look at "svn diff" 
output, for  example, differences between the source branch and the target 
branch in  other lines of the file are  hidden even though they might be 
important for the correctness of the  patched lines.)
+ {{{#!wiki note
+ The merge algorithm cannot possibly "know" by inspection whether the physical 
change that was committed as a merge is a ''faithful'' representation the set 
of logical changes that the mergeinfo claims it is.  As far as merge tracking 
is concerned, if the mergeinfo says a given logical change was merged, it was 
merged.  User interfaces should try to assist the user in understanding this.
+ }}}
  
- It's important to consider complex examples of change.  A change like  adding 
"This is a new line" to the end of file "foo" is often too simple  to 
demonstrate merge tracking requirements.  With such an example, the  tree-merge 
layer is quite likely to DTRT no matter what the merge  tracking layer says.  
But important changes aren't always like that;  important changes often can't 
be automatically merged at the tree-merge (or text-merge) level.
+ {{{#!wiki note
+ The UI may also provide the user with a way to tell Subversion that he/she 
has merged a given logical change into the WC manually (not using the 'merge' 
command), or has merged a change into the WC and then decided to remove it 
before committing and not record it as merged.  The command-line interface for 
these is "svn merge --record-only".
+ }}}
  
  IMPLEMENTATION
  
- Of course the merge tracking implementation is written in terms of  tracking 
physical changes (commits), not logical changes.  In simple  cases that gives 
exactly the same result, but I view the ''purpose'' as  being to track logical 
changes, and so when we consider cases where the  two approaches require 
different outcomes then I look at the latter.
+ The merge tracking implementation is written in terms of tracking physical 
changes (commits), not logical changes.  In simple cases that gives exactly the 
same result.  In particular, it gives the same result when merging from branch 
A to branch B if we have only ever been merging from branch A to branch B.  
When we introduce a third branch C, however, and wish that merge tracking would 
continue to work when we merge from A to B to C to A to C to B to ..., that's 
when we need to make the distinction.
+ 
+ Since Subversion 1.5 (through 1.8 at least), the merge tracking stores 
mergeinfo ''transitively'', so after merging a change from A to B to C, the 
mergeinfo on branch C will list both the change on branch B that was merged 
directly to C, and also the change(s) in branch A that were merged directly to 
branch B and therefore indirectly to branch C.  This partly serves to make the 
merge tracking act as if it is tracking logical changes.  A subsequent merge 
from A to C will not repeat the same changes that are recorded as already merge 
(indirectly) from A to C, and so in that case it correctly avoids re-merging 
the logical changes from A that are already on C.  But if we try things another 
way round -- first merge from A to C, and then from A to B to C, the last merge 
(B to C) will wrongly repeat the changes that already arrived on C in the first 
merge (directly from A).
  
  == Merging Scenarios for Subversion 1.6 ==
  ||||<style="text-align:center;">'''Key''' ||
@@ -149, +151 @@

  Other possible kinds of merging include taking any arbitrary difference 
between two files or directories -- perhaps on different branches or without 
any branching history connecting them -- and merge that difference into some 
other file or directory  (perhaps unrelated to either side of that diff).  
Merge tracking does not try to address such cases, and so we do not consider 
them here.
  
  === Note 2 ===
- If this change is being merged into a target WC in which other changes have 
also being merged, and touches some of the same nodes, then similarly this 
change is also adapted (automatically and/or through manual conflict 
resolution) to  combine with those other changes.
+ Although what we mean by the physical manifestation of a change is kind of 
obvious, in fact it is subtly hard to pin down, because it depends entirely how 
you represent the physical change.
  
+ === Note 3 ===
+ Also, if this change is being merged into a target WC in which other changes 
have also being merged, and touches some of the same nodes, then similarly this 
change is also adapted (automatically and/or through manual conflict 
resolution) to  combine with those other changes.
+ 

Reply via email to