Symmetric merge and deleted subtrees
From: Julian Foad <julianfoad_at_btopenworld.com>
Date: Tue, 31 Jul 2012 18:50:12 +0100 (BST)
I'm investigating a discrepancy that shows up, when 'symmetric merge' is enabled [1], in the notifications printed by some merges. Merge_tests 78 fails because the expected notification for the last merge is:
--- Merging r6 through r9 into 'H_COPY':
U H_COPY/psi
D H_COPY/nu
--- Recording mergeinfo for merge of r6 through r9 into 'H_COPY':
U H_COPY
but the first line of that changes to:
--- Merging r7 through r9 into 'H_COPY':
while the rest stays the same. In this instance the difference is probably harmless since r6 is a no-op in the merge source, but we need to check whether this is a symptom of a wider problem.
NEW TEST FOR THIS ISSUE
I have simplified the recipe into a new test, merge_tests-130 in
the attached patch [2]. I removed the '--force' option, and this changes things such that the merge prints a separate notification for the subtree. Also
in that patch are some debug prints in the merge code which help to
trace the source of the problem. A diagram of the test scenario:
# merge -c4 A/D/H/nu@4 H_COPY/nu
# | merge A/D/H H_COPY
# | |
# A/D/H A---------------
# +-psi +---------M-----
# +-nu A---M-D
# H_COPY C----------G
# +-psi +----------+
# +-nu +-------G--+
# 1 2 3 4 5 6 wc wc
#
# Key: Add Mod Del Copy merGe
The difference in outputs ('-': existing 1.7 merge, '+': symmetric merge):
I: CMD: svn merge ^/A/D/H H_COPY
I: DBG: merge.c:8568: 1: ...130/H_COPY: 3-6
I: DBG: merge.c:8568: 1: .../H_COPY/nu: 3,5-6
I: DBG: merge.c:8568: 2: ...130/H_COPY: 3-6
I: DBG: merge.c:8568: 2: .../H_COPY/nu: 3,5-6
I: DBG: merge.c:8568: 3: ...130/H_COPY: 3-6
-I: DBG: merge.c:8568: 3: .../H_COPY/nu: 3-6
+I: DBG: merge.c:8568: 3: .../H_COPY/nu: 3,5-6
-I: --- Merging r3 through r6 into 'H_COPY':
+I: --- Merging r4 through r6 into 'H_COPY':
I: U H_COPY/psi
-I: --- Merging r3 through r6 into 'H_COPY/nu':
+I: --- Merging r5 through r6 into 'H_COPY/nu':
I: C H_COPY/nu
I: --- Recording mergeinfo for merge of r3 through r6 into 'H_COPY':
I: U H_COPY
I: --- Recording mergeinfo for merge of r3 through r6 into 'H_COPY/nu':
I: G H_COPY/nu
I: --- Eliding mergeinfo from 'H_COPY/nu':
I: U H_COPY/nu
I: Summary of conflicts:
I: Tree conflicts: 1
The immediate cause of the discrepancy is that the symmetric merge code
passes the YCA revision as the beginning of the range to be merged,
whereas the existing merge code passes revision '1' as the beginning of
the range to be merged. At the beginning of the main loop in do_merge():
- source = {loc1 = "/A/D/H@1", loc2 = "/A/D/H@6", ancestral = TRUE}
+ source = {loc1 = "/A/D/H@2", loc2 = "/A/D/H@6", ancestral = TRUE}
The underlying problem -- the reason why the merge code doesn't resolve these two requests to the same result -- is deeper, involving the function fix_deleted_subtree_ranges(). That function yields
(child 'H_COPY/nu')->remaining_ranges = 3-6
for the 1.7 merge and
(child 'H_COPY/nu')->remaining_ranges = 3,5-6
for the symmetric merge.
Revision 4 has already been merged to 'H_COPY/nu', so it should not be merged again; but that doesn't mean 'remaining_ranges = 3-6' is wrong. fix_deleted_subtree_ranges() is designed to set a subtree's remaining range to match its parent's remaining range if the subtree doesn't need a separate editor drive. The function appears to be concluding in the first case that the subtree doesn't need a separate editor drive (since, over the range 3-6, the net result is simply to delete the subtree), but in the second case that it does and should be split into two sub-ranges.
I'm not sure whether one of those conclusions is right and the other wrong; maybe both are OK. I'm not sure why there are two different conclusions.
TREE CONFLICT
Another issue I have identified here is that, in either case, a tree conflict is flagged unnecessarily on 'nu'. (That doesn't happen in merge_tests-78 because that test passes the '--force' flag.)
In the 1.7 case, the merge reports that it is merging 'r3 through r6', and the conflict details are reported as:
$ svn info H_COPY/nu
Tree conflict: local edit, incoming delete upon merge
Source left: (file) ^/A/D/H/nu@1
Source right: (file) ^/A/D/H/nu@6
First, we notice that the reported 'left' and 'right' details don't match up with the description as an incoming 'delete'. I recall that's a long-standing error in the conflict reporting.
The working file to be deleted ('H_COPY/nu' with r4 merged in to it) has content that doesn't match the expected pre-delete content (A/D/H/nu@2, because the revs to be merged are 3-6). I haven't checked the detection code yet, but if that's why the conflict is flagged, then clearly the tree-conflict logic that says 'the content should match that at the beginning of the range being merged' is incompatible with the logic of fix_deleted_subtree_ranges() which says 'there is no need to calculate the exact ranges to be merged if the end result is just a delete'.
In the symmetric merge case, the merge reports that it is merging 'r5 through r6', and the conflict details are:
Tree conflict: local edit, incoming delete upon merge
Source left: (file) ^/A/D/H/nu@2
Source right: (file) ^/A/D/H/nu@6
I don't know why that's flagging a conflict there -- do we flag a conflict just because it has local mod, regardless that it may have the expected content?
CONCLUSIONS SO FAR
* There's a deficiency in fix_deleted_subtree_ranges() -- it should at least give consistent results with these two different input ranges.
* As a temporary or diagnostic measure we might be able to make 'symmetric merge' give the same result by making it pass the oldest possible revision (1) instead of the YCA revision (2) as the beginning of the range to consider.
* There's a deficiency in conflict detection.
I will continue to investigate all of this, but any assistance is very welcome.
- Julian
[1] Patch to enable symmetric merge: attachment 'use-symmetric-merge-1.patch'.
[2] New test and debug prints: attachment 'deleted-subtree-ranges-1.patch'.
--
Certified & Supported Apache Subversion Downloads: http://www.wandisco.com/subversion/download
|
This is an archived mail posted to the Subversion Dev mailing list.
This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.