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
test.sh
Description: Bourne shell script