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:

http://svn.apache.org/repos/asf/subversion/branches/moves-scan-log/BRANCH-README

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
  Rationales:
  - 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.
  Rationales:
  - 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 ;
  Rationales:
  - 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.
  Rationales:
  - 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.
  Rationales:
  - 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
    warranted.

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
  "continue".
* Finally, all text changes get applied to their
  respective target paths.

Notes:

* 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
  future.
* 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.

Reply via email to