On Fri, Jan 25, 2013 at 12:32 PM, Paul Burba <ptbu...@gmail.com> wrote:
> On Fri, Jan 25, 2013 at 12:11 PM, Paul Burba <ptbu...@gmail.com> wrote:
>> On Thu, Jan 24, 2013 at 5:16 PM, Julian Foad <julianf...@btopenworld.com> 
>> wrote:
>>> Summary: I plan to make 'svn merge' act on --accept=theirs|mine|etc. per 
>>> file, rather than (as it does now) postponing all conflicts until after the 
>>> whole merge and then resolving them.
>>>
>>>
>>> I have been investigating the way "--accept=foo" resolves conflicts, for 
>>> blocker issue #4238 "merge -cA,B with --accept option aborts if rA 
>>> conflicts" [1].  Postponing all resolution until the end of the whole merge 
>>> (as we do now) is not good enough in this scenario.  A similar scenario can 
>>> occur during an automatic merge when the merge code internally decides to 
>>> do a multi-revision-range merge.
>>
>> Minor nit: The internal split you speak of here isn't tied solely to
>> automatic merges.  Cherry-picks can provoke that behavior just as
>> easily.  For example:
>>
>> svn merge  SRC TGT -cY
>> svn merge SRC TGT -rX:Z
>>
>> Where X < (Y-1) < Y < Z
>>
>> The second merge will be split into two parts: X:(Y-1), Y:Z
>>
>> I mention this only because the issue #4238 scenario of
>>
>>   svn merge -cM,N
>>
>> Could just as easily be,
>>
>>   svn merge -rW:X,Y:Z
>>
>> and either one of those ranges could be split into multiple merges.
>>
>>> We need to be able to resolve conflicts at least after each phase (revision 
>>> range) of merge.
>>>
>>> For the manual '-cA,B' example the client ('svn') could simply call 
>>> svn_client_merge once for each specified revision or range, resolving any 
>>> conflicts after each.  That is not feasible for the ranges decided 
>>> internally during an automatic merge, because the client doesn't have a way 
>>> to discover those ranges in advance.  (And the merge code architecture is 
>>> such that it discovers those ranges incrementally as it goes.)
>>
>> I just realized another problem for automatic (implied) or cherry-pick
>> (explicit) ranges in which a given range is split into multiple merges
>> under the covers: We record mergeinfo based on the requested merge
>> range, even if only part of the range is merged before we hit a
>> conflict and abort.  This prevents the remainder of the range from
>> being merged if the conflict is resolved and the merge repeated.
>>
>> A simple example (borrowing the WC from the issue #4238 test prior to
>> the merge):
>>
>> ### Copy a file:
>>
>>>svn copy iota@1 iota-new
>> A         iota-new
>>
>>>svn ci -m "" -q
>>
>> ### Merge a rev from the middle of all eligible revs and commit:
>>
>>>svn mergeinfo --show-revs eligible ^^/iota iota-new
>> r2
>> r3
>> r4
>>
>>>svn merge ^^/iota iota-new -c3 --accept theirs-conflict
>> --- Merging r3 into 'iota-new':
>> C    iota-new
>> --- Recording mergeinfo for merge of r3 into 'iota-new':
>>  U   iota-new
>> Summary of conflicts:
>>   Text conflicts: 1
>> Resolved conflicted state of 'iota-new'
>>
>>>svn ci -m ""
>> Sending        iota-new
>> Transmitting file data .
>> Committed revision 6.
>>
>>>svn up -q
>>
>> ### The expected mergeinfo:
>>
>>>svn pl -vR
>> Properties on 'iota-new':
>>   svn:mergeinfo
>>     /iota:3
>>
>> ### Do a merge which covers a range of revs which the previously merged
>> ### rev is a proper subset of (nothing new here, this is just the "internally
>> ### decided" range split Julian spoke of.
>>
>>>svn merge ^^/iota iota-new
>> --- Merging r2 into 'iota-new':
>> C    iota-new
>> --- Recording mergeinfo for merge of r2 through r6 into 'iota-new':
>>  U   iota-new
>> Summary of conflicts:
>>   Text conflicts: 1
>> Conflict discovered in file 'iota-new'.
>> Select: (p) postpone, (df) diff-full, (e) edit, (m) merge,
>>         (mc) mine-conflict, (tc) theirs-conflict, (s) show all options: p
>> ..\..\..\subversion\svn\util.c:553: (apr_err=155015)
>> ..\..\..\subversion\svn\merge-cmd.c:138: (apr_err=155015)
>> ..\..\..\subversion\libsvn_client\merge.c:11611: (apr_err=155015)
>> ..\..\..\subversion\libsvn_client\merge.c:11582: (apr_err=155015)
>> ..\..\..\subversion\libsvn_client\merge.c:9057: (apr_err=155015)
>> ..\..\..\subversion\libsvn_client\merge.c:4715: (apr_err=155015)
>> svn: E155015: One or more conflicts were produced while merging r1:2 into
>> '\iota-new' --
>> resolve all conflicts and rerun the merge to apply the remaining
>> unmerged revisions
>>
>>>svn st
>> CM      iota-new
>> ?       iota-new.merge-left.r1
>> ?       iota-new.merge-right.r2
>> ?       iota-new.working
>> Summary of conflicts:
>>   Text conflicts: 1
>>
>> ### Obviously we only merged r2 before things blew up, but
>> ### not according to the resulting mergeinfo :
>>
>>>svn pl -vR
>> Properties on 'iota-new':
>>   svn:mergeinfo
>>     /iota:2-6
>>
>> ### Obviously this means if we resolve the conflict...
>>
>>>svn resolved -R .
>> Resolved conflicted state of 'iota-new'
>>
>> ### ...and repeat the merge, then r4 stubbornly remains un-merged:
>>
>>>svn merge ^^/iota iota-new
>>
>> ### Even if we explicitly ask for r4:
>>
>>>svn merge ^^/iota iota-new -c4
>>
>> ### We have to disable merge tracking and use a cherry-pick to DTRT
>> ### (i.e. get r4 applied) which is, to put it charitably, less than optimal:
>>
>>>svn merge ^^/iota iota-new -c4 --ignore-ancestry
>> --- Merging r4 into 'iota-new':
>> C    iota-new
>> Summary of conflicts:
>>   Text conflicts: 1
>> Conflict discovered in file 'iota-new'.
>> Select: (p) postpone, (df) diff-full, (e) edit, (m) merge,
>>         (mc) mine-conflict, (tc) theirs-conflict, (s) show all options: p
>>
>>>
>>
>> FWIW this isn't a regression from 1.7.  I'll file an issue and add a
>> test shortly.
>
> Issue: http://subversion.tigris.org/issues/show_bug.cgi?id=4306
> Test: http://svn.apache.org/viewvc?view=revision&revision=1438602

Turns out only file merges were susceptible (which explains why we
haven't had lots of complaints about this previously).  Fixed in
http://svn.apache.org/viewvc?view=revision&revision=1438683

-- 
Paul T. Burba
CollabNet, Inc. -- www.collab.net -- Enterprise Cloud Development
Skype: ptburba

Reply via email to