subversion-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Julian Foad <julianf...@btopenworld.com>
Subject Re: E195016 on trying a normal merge / is_reintegrate_like determined correctly?
Date Fri, 04 Sep 2015 13:03:23 GMT
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@6 "completely"
> merged to source because target@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@3, except for mergeinfo)

# By inspection, the content group (Trunk@3, Branch@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@5 == Trunk@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@3.
#   ==> Correct.
#
# It sees Branch@5 as a change that hasn't been merged to Trunk, so
# youngest Branch rev completely merged to Trunk is Branch@4.
#   ==> Correct, in the sense that "all changes here are also there".
#
# It sees Trunk@3 and Branch@4 as potential YCAs, and chooses Branch@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@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@4 as the
# base for the requested merge.

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

- Julian

Mime
View raw message