You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Gino Marckx <gi...@xodiac.be> on 2005/04/07 07:08:47 UTC

RE: Merge tracking

Hi there,

I saw that the discussion about merge tracking has been opened again,
which is a very good thing.  In my opinion this is THE major reason why a
company would choose to use ClearCase instead of Subversion.
Most documentation I read so far lacked one important issue though.  When
using parallel development in a company, a lot of branches are created,
resulting in a lot of merge actions in the end.

I usually work with the following sheme: there is a main branch for every
major release, and subbranches for every feature.  All features are
developed separately and when fully tested and production ready, they are
integrated in the main branch.  Now, before integration, the changes in
the main branch (e.g. integration of other features) need to be merged
into the feature branch, to test the integration locally.  If all unit
tests work, the complete feature branch can be integrated and closed.  I
like to call these actions rebase and integrate.  A rebase is a merge from
the parent branch to the child branch, an integrate is the other way
around.

There are a few things to keep in mind when using Subversion with this
branching scheme.

1. Off course, it is wise to rebase regularly, to test the integration in
small steps, every time a feature is integrated in the main branch.  It is
important that what has been merged in a previous rebase is not merged
again.  But everybody is aware of this problem and it has been documented
a few times already.

2. When integrating, the changes on the child branch that result from the
rebase action (and thus are coming from the parent branch) do not need to
be integrated in the parent branch.  Otherwise these changes will be
duplicated.  Solving this means that somehow the merge tool needs to know
that changeset X is already in the parent branch.  Solving this also means
solving 'transitive merges'.  Given branches A, B and C, these are a few
examples of what I call 'transitive merges':
- if A:3 is merged into B:5 and A:3 is merged into C:7, then a merge from
B:6 into C:8 needs to ignore the changeset from the merge from A:3 into
B:5
- if A:3 is merged into B:5 and B:5 is merged into C:7, then a merge from
A:6 into C:8 needs to ignore the changeset from the merge from A:3 into
B:5

3. What if the rebase action results in on or more conflicts?  The
conflicts will be solved in the child branch and committed.  This
changeset will be registered as the merge.  But when integrating, this
changeset is ignored because of the situation explained in 2.  So there
will be a conflict again.  This is off course inacceptable.  When doing
the merge manually, you would copy the conflicting files from the child
branch to the parent branch, but this is of course only possible when you
are sure nothing changed on the parent branch since the last rebase.  How
could we solve this?  In my opinion, this is the most difficult part of
the merge tracking problem...


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: Merge tracking

Posted by Gino Marckx <gi...@xodiac.be>.
>> 2. When integrating, the changes on the child branch that result from
>> the rebase action (and thus are coming from the parent branch) do not need
>> to be integrated in the parent branch.  Otherwise these changes will be
>> duplicated.
>
> If you have brought the branch up to date, i.e. you have rebased it up to
> the current head revision, then integrating is simply equivalent to copying
> the branch to the trunk.  (The change that needs to be added to the
trunk is
> simply the current difference between trunk and branch.)

That is correct, and I also suggested that in the third point of my
original posting.  You only need to be sure that nothing has happened on
the trunk between your 'rebase' and your 'copy', otherwise, these changes
are overwritten.

> If you haven't yet brought the branch up to date, then there are likely to
> be conflicts and you shouldn't be trying to integrate it.

Well, it depends.  I also think it is good practice to do the integration
on the local branch and not directly on the parent branch or trunk, but
nothing prevents you from doing that.

> So I don't see why you would need transitive merges etc. in this
> situation.

In fact, a rebase/integrate cycle is kind of a transitive merge.  Say that
we have parent branch P and child branch C.  C branched from P at revision
3.  After developing a while on branch C, we want to do a rebase.  But in
the mean time, P has been changed by changesets 5 and 6.  The rebase
action results in changesets 5 and 6 to be merged in C, commited in
revision 8.  Now, if we want to integrate C in P, we need to merge the
changes on C from revision 3 to 7 (excluding 8) to get it right.  When
merge tracking is implemented, I assume that I would just be able to merge
from 3 to HEAD, and that the merge tool would notice that revision 8 is
not really 8, but 5 and 6 from the parent branch, so it would not be
integrated anymore (or replace 5 and 6, see my note below).  So a
rebase/integrate cycle is kind of transitive from P to C and then from C
to P.  But indeed, true transitive merges (with at least 3 parties) are
not applicable in this situation.  I only think that solving the
rebase/integrate cycle problem will also solve the transitive merge
problem.

* Now what was that nonsense about replacing changesets?
Well, in my original posting, I wrote the following:
> 3. What if the rebase action results in one or more conflicts? ... when
> integrating, this changeset is ignored because of the situation explained
> in 2.  So there will be a conflict again ... When doing the merge manually,
> you would copy the conflicting files from the child branch to the parent
> branch...
What if instead of doing a copy on an integrate, you would be able to
replace the changesets that are merged by the changeset which recorded the
merge?  Off course this would need to be generalized like this: "Merging a
changeset M that is itself the result of a merge from changesets C1 to Cn
that the target branch already contains, is done by replacing the original
C1 to Cn by M on the target branch".  Would this be valid?  Would this be
possible and solve our problem?
What would the merge tool do when trying to merge M (result of merging C1
and C2) to a branch containing only changeset C1?  It cannot do the
replacement trick there.  Whould it try to merge only C2?  Or should it
result in a conflict?  I assume the latter is the only correct solution,
since we would not be able to consider other possible changes that are
commited in M.

Gino


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: Merge tracking

Posted by Julian Foad <ju...@btopenworld.com>.
Gino Marckx wrote:
> 2. When integrating, the changes on the child branch that result from the
> rebase action (and thus are coming from the parent branch) do not need to
> be integrated in the parent branch.  Otherwise these changes will be
> duplicated.

If you have brought the branch up to date, i.e. you have rebased it up to the 
current head revision, then integrating is simply equivalent to copying the 
branch to the trunk.  (The change that needs to be added to the trunk is simply 
the current difference between trunk and branch.)

If you haven't yet brought the branch up to date, then there are likely to be 
conflicts and you shouldn't be trying to integrate it.

So I don't see why you would need transitive merges etc. in this situation.

- Julian

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org