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

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

Reply via email to