On Mon, Jan 9, 2012 at 6:14 AM, Julian Foad <julianfoad_at_btopenworld.com> wrote:
> Merging would be simpler if the user didn't have to think about doing the "keep-alive dance" after a reintegrate [1].
>
> I'm trying to teach the sync merge to detect when a reintegrate has been done, so that we could avoid the need for r45 in the following typical sequence:
>
> | Rev Branch Commit
> | A B
> |--------------------
> | r10 X
> | | \
> | r20 | X "New branch B, a copy of A."
> | | |
> | r30 | X "Modify B."
> | | / |
> | r40 X | "Reintegrate from B into A."
> | | \ |
> | r45* | X "Record-only merge to keep B alive."
> | | |
> | r50 X | "More work in A."
> | | \ |
> | r60 | X "Sync from A into B."
>
> A patch in progress is attached. It makes 'merge' detect when one of the revision ranges to be merged would include changes that have
> already been merged in the opposite direction. At present it stops the merge, giving a friendly error message.
>
> I would like to make it skip the particular revision(s) and continue to merge all the other revisions in the range, but first we need to get the detection right.
Hi Julian,
Let me first say that I am all for trying to make this work. The need
to delete and recreate a branch or use --record-only to block it,
after reintegrating is not very user-friendly. That said, I think
you'll find this trickier than it looks at first glance...
> Using the above example, if we don't do the r45 record-only merge, then during the last sync merge (which will be committed in r60), the normal merge tracking code first determines that the revision range to be merged is r11-r50 [2]. Then the new code detects that this incoming change brings in new mergeinfo about merges *from* the current target branch B. Therefore the new code will stop and complain.
>
> That's all right for simple cases but it's not good enough.
>
> We can say for sure that when we reintegrated B to A (in A:40), that will have added new mergeinfo on A describing merges from B. However, if change A:40 had instead been a different merge into A, let's say from C, it is still possible that merge might have brought along some new mergeinfo describing merges from B, because of the way mergeinfo is propagated from branch to branch. Therefore, if we find that change A:40 adds new mergeinfo about merges from B, we cannot simply say that A:40 describes a reintegrate merge from B.
Absolutely! There's also the similar case where 'B' is reintegrated
to 'A', additional edits are made to 'A', and then the whole thing is
committed as r40. Now r40 represents both the reintegrate change and
unrelated edits -- but of course the smallest unit mergetracking works
with is a revision, so how does it classify r40?
> We need to look more closely. That's what I'm currently working on.
This runs up against issue #2897 'Reflective merges are faulty'. You
seem to be acknowledging this with your comments in the patch itself:
"Note that with all these improvements, the result might approach a more
flexible merge system in which any reflected or cyclic changes are skipped,
*BUT WOULD NOT COPE* (emphasis mine) with the case where a revision
in the source branch contains a mixture of changes merged from the target
branch and other changes."
But if we can't cope with that case how can we do anything that's an
improvement over what we do today (i.e. just merge r40)? We can't
skip r40 based on mergeinfo alone because there might be other
legitimate changes. If we merge r40 that means we determined that
*some* of the changes in that revision are legitimate. Do we apply
only the fractional part of r40 that is legitimate? In other words,
this whole thing appears to be a non-starter unless we can fix issue
#2897. Is that your intention?
Paul
> Comments?
>
> - Julian
>
>
> [1] See the end of <http://wiki.apache.org/subversion/KeepingReintegratedBranchAlive>.
> [2] Assume HEAD is r50 at this time.
Received on 2012-01-10 19:52:18 CET