[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Rename tracking for merges

From: Stefan Fuhrmann <stefanfuhrmann_at_alice-dsl.de>
Date: Tue, 01 May 2012 10:02:10 +0200

Hi Mergeans,

One of main sources for merge conflicts in SVN
is its inability to follow renames. Philip and
(the other) Stefan already made some attempts to
solve that issue on the client side:


After some discussion on the list and with Julian
on IRC, I think I found the following workable
model and I would like to start implementing it
on some branch.

-- Stefan^2.

Data spec:

* Introduce a new revprop svn:mergehints
   - Being a move is a property of the change,
     not the node / node content.
   - The user must be able to identify renames /
     moves after the fact. She may also revise
     that decision afterwards.
   - Since add and del may be committed in separate
     revisions, an online analysis may be expensive
     ab become more sophisticated in the future.
     Having the revprop, we can use a separate tool
     that analysis the repo and stores the results
     in said revprop(s).

* Info in svn:mergehints is non-authoritative.
   A client may ignore them in parts or entirely
   but it must issue a warning when it does.
   - The intention is to aid the merge algorithm
     in its decision making - not to force it to
     mess up your source tree.
   - In some cases, the hints may be conflicting
     or not matching the actual change history
     (e.g. typo in path name)
   - In some cases, the algorithm might not support
     a specific hint or some of its parameters
     (backward compatibility)

* Use the following format
   mergehints = { hint } ;
   hint = keyword [ parameters ] "\n" { sub-hint } ;
   keyword = "continue" | "ignore" ;
   parameters = utf8-string-without-newlines ;
   sub-hint = whitespace { whitespace } hint ;
   - We can add arbitrary keywords in later versions
   - Some descriptions may not fit well into a single
     line. So, allow for sub-info to be put on extra lines
   - Make the top-level hints and keywords clearly
     identifiable such that unsupported ones can be
     skipped generically.

* "continue" from-path[@peg] [ from-rev ] to-path
   Specifies that the merge-relevant change history
   of from-path,from-rev is continued by to-path,
   current rev carrying this revprop. From simplicity,
   from-rev can be the deletion rev but the deletion
   will not become part of the combined history.
   - Could also be called "link" but that might be
     mistaken for OS file system links.
   - Allow for @peg rev just for consistency with
     other UI
   - From-rev is useful to bridge gaps between the
     rev in which from-path was deleted and the one
     carrying this merge hint.

* "ignore" path [[from-rev:]to-rev]
   Makes the merge ignore changes on path (including
   the sub-tree) in the given revision range.
   Revisions not given are set to current. to-rev may
   be HEAD. Copy-from history is not being followed and
   deletes terminate the range.
   - Useful to mark branch-specific changes / nodes.
   - Useful to model cases where there is a "continue"
     statement for this path @to-rev+1
   - Termination helps with the ranges like 0:HEAD
     and also clarifies the interaction with "continue".
   - A distinction between directory property-only
     changes and sub-tree changes doesn't seem to be

Semantics in a merge from path A to path B:

* All mergehints from the YCA are being evaluated in
   revision order, separately for A and B.
* If A and B are unrelated (no YCA exists), "continue"
   hints will be ignored.
* "continue" and "ignore" do not affect the merge of
   tree changes. However, the merge might use them to
   resolve tree conflicts. But that part will not be
   specified here.

* Starting from the YCA, the "continue" information
   is being collected and applied. For each node, this
   yields a list of changes (node, rev) on the source
   side A and a target path (node) on the target side B.
   If beneficial to the merge algorithm, we can also
   derive the change list (node, rev) of the target side.
* "ignore" is then applied to reduce the entries in
   the source lists, i.e. "ignore" takes precedence over
* Finally, all text changes get applied to their
   respective target paths.


* The hints are being evaluated at merge time. Later
   changes done by the user will not "mend" previous
   merges but may help to produce better results in the
* The design allows for N:1, 1:N and N:M merges
   (e.g. multiple continuations to the same target)
   but we will support 1:1 only in our initial implementation.
   Technically, we can use that feature to model changes
   in file granularity.
Received on 2012-05-01 12:03:12 CEST

This is an archived mail posted to the Subversion Dev mailing list.