[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: E195016 on trying a normal merge / is_reintegrate_like determined correctly?

From: Julian Foad <julianfoad_at_btopenworld.com>
Date: Fri, 4 Sep 2015 14:03:23 +0100

I (Julian Foad) wrote:
> Stefan Hett wrote:
>> running the attached test script brings up the following error:

(The attached 'test.sh' is a translation to Bourne shell of your
'test.txt'.)

>> "E195016: Reintegrate can only be used if revisions 2 through 8 were
>> previously merged from [branchURL] to the reintegrate source, but this is
>> not the case:
>> trunk
>> Missing ranges: branches/A:2,5"
>>
>> The weird thing here (at least weird in my understanding) is that it
tries
>> to do a reintegration merge even though I'm trying to perform a catach-up
>> merge with trunk on the branch.
>>
>> Looking at merge.c at line 12462 the following if-check determines it's a
>> "reintegrate-like" merge and therefore tries to do a reintegration merge,
>> instead of a "normal" merge:
>> if (base_on_source->rev >= base_on_target->rev)
>>
>> base_on_source->rev = 3
>> base_on_target->rev = 4
>>
>> I'm wondering whether this if-check suffices here to determine whether
it is
>> a reintegration merge or not, given my test-scenario which has
cherry-picked
>> revisions in both directions (trunk <-> branch).
>> To me it looks like the check relies on cherry-picking only being
performed
>> in one or the other direction, because otherwise the
>> "youngest-complete-synced-point" couldn't be used to determine the
direction
>> for reintegration merges...
>
> By "complete synced point" I would mean a branch-revision (such as r4
> on target) at which *all* changes up to this point have been merged to
> the other branch. A cherry-picked revision after that (say r6 on
> target was merged to source) wouldn't make target_at_6 "completely"
> merged to source because target_at_5 is missing.

Let me draw some diagrams to illustrate what is going on.

(I'm switching to HTML in order to specify a fixed-width font.)

# Showing Add, Add+history, Modify, merGe:

    1 2 3 4 5 6 7 8
Tr A [M] M M G
      \ \____ ____/ \
       \ \ / \
Br A+ G [M] G?

$ svn pg svn:mergeinfo trunk branches/A
trunk - /branches/A:6
branches/A - /trunk:2-3

$ svn mergeinfo --show-revs=merged trunk branches/A
r3

$ svn mergeinfo --show-revs=merged branches/A trunk
r6

$ svn mergeinfo --show-revs=eligible trunk branches/A
r4
r7
r8

$ svn mergeinfo --show-revs=eligible branches/A trunk
r5

# Showing [merged] and *eligible* changes:

    1 2 3 4 5 6 7 8
Tr A [M] *M* *M* *G*
      \ \____ ____/ \
       \ \ / \
Br A+ *G* [M] G?
        ^
        No change here

# Grouping of identical content linked by double lines (==, \\):

    1 2 3 4 5 6 7 8
Tr ====== == ========== == =====
     \\ \\ / \
      \\ \====\ / \
       \\ \\ [ ]___/ \
Br ========== == ========== ?
                    ^
                    Fast-forward merge
                    (content == Trunk_at_3, except for mergeinfo)

# By inspection, the content group (Trunk_at_3, Branch_at_5) is the best
# ('youngest') common ancestor.

# Subversion doesn't distinguish a fast-forward merge as a special
# case -- it doesn't recognize that Branch_at_5 == Trunk_at_3. It treats
# it as a general merge and sees:

    1 2 3 4 5 6 7 8
Tr ====== == ========== == =====
     \\ \ / \
      \\ \____ / \
       \\ \ [ ]___/ \
Br ========== == ========== ?

# It sees youngest Trunk rev completely merged to Branch is Trunk_at_3.
# ==> Correct.
#
# It sees Branch_at_5 as a change that hasn't been merged to Trunk, so
# youngest Branch rev completely merged to Trunk is Branch_at_4.
# ==> Correct, in the sense that "all changes here are also there".
#
# It sees Trunk_at_3 and Branch_at_4 as potential YCAs, and chooses Branch_at_4
# as the 'later' of them based on their revision numbers.
# ==> Wrong: it should choose the 'later' of them based on graph
# ordering of content groups, not on ordering of particular
# revision numbers of the same content.

$ svn mergeinfo trunk branches/A
    youngest common ancestor
    | last full merge
    | | tip of branch
    | | | repository path

    1 8
    | |
  -------| |------------ trunk
     \ /
      \ /
       --| |------------ branches/A
              | |
              4 WC

# So that's why the 'svn mergeinfo' diagram shows Branch_at_4 was the
# last thing fully 'merged' in either direction, although it wasn't
# actually merged. And that means it will try to use Branch_at_4 as the
# base for the requested merge.

I conclude that Subversion isn't doing the best we could do.

- Julian

  • application/x-sh attachment: test.sh
Received on 2015-09-04 15:04:00 CEST

This is an archived mail posted to the Subversion Dev mailing list.