blob: a9c5bd9a2b8aaac46325229291762e74cf860935 [file] [log] [blame]
IMPLEMENTATION PLAN
===================
The plan for building a Merge Tracking implementation for Subversion's
core <http://subversion.tigris.org/merge-tracking/>.
Phase 1: Target for the 1.5.0 release
-------------------------------------
Record and use merge history to avoid the repeated merge problem and
allow for cherry-picking. Expose merge info via properties. Allow
for repos dump/load (including the ability to re-create the merge
history index).
* Provide an API for merging arbitrary revision ranges ('-c 3,5,7' or
'-r 2:3,9:12'). Client tools will use this to best support
cherry-picking. Command-line client UI to follow post-1.5.
* Write libsvn_client API.
* Write corresponding JavaHL bindings. (dlr/markphip)
* Provide a libsvn_client API capable of listing "all unmerged
revisions". Client tools will use this to allow the user to select
the revisions to merge via 'svn log --merges-available-from=[URL]'.
(kamesh)
* Always recurse (in case child merge info differs), but support the
--depth option.
* Handle notifications resulting from a merge. (sussman)
* Handle multiple notifications for single WC items.
* Output multiple notifications, but print divider lines
indicating the revisions range to which a set of notifications
applies. This will require enhancing the notification API to
include enough context to indicate which revision range is
currently being merged. Introduce a new type of "skipped"
notification for WC items which are already in conflict.
* Document potential wrapper for the above API, something which we
won't be implementing: Collate changes as merge ranges are
applied. Detect and handle collisions (multiple notifications
to the same WC item), giving preference to later notifications.
* Handle skips.
* If only some changes are skipped, merge info should be recorded
for the target (implemented r25085), and recorded as empty (or
with no modifications, if there is pre-existing merge info) for
the skipped items.
* Handle conflicts.
* If a conflict is encountered, invoke a conflict resolution
callback to give a Subversion client a chance to intervene. If
resolution is successful, convert the notification from a 'C' to
something else (e.g. 'M'). (Phase 2?)
* Otherwise, stop applying merge ranges as soon as a second
conflict is encountered in a WC item (as it might generate
overlapping conflict makers, or apply a merge inside a conflict
marker!), being sure to record partial application of merge
ranges.
Update (2007/04/23): Discussion with some Subversion dev
Googlers indicate that they'd prefer a more comprehensive
solution which allows interactivity to be deferred until all
possible merging has occurred. (They are not alone in a desire
to see this use case handled.)
* Add a notification message or perhaps a notification callback so
that a client may provide detailed information about the state of
the merge. Something which identifies which revisions have been
merged and that the user needs to resolve the conflicts and then
restart the merge process to allow it to pick up where it left off.
* Handle merge info inheritance (and eliding, if any additional work
is necessary). (pburba/dlr)
* Fix bug on merge to target with moved/copied children,
issue #2754. (pburba)
* Improve merge algorithm used for target trees with child paths
that contain differing merge info, per Peter Lundblad's
suggestions. See the following thread:
http://subversion.tigris.org/servlets/BrowseList?list=dev&by=thread&from=565086
* Treat all revisions from a 'copy' source as merge info for the
destination. This equates to turning all those revs into actual
merge info (target merge info = source revs + source merge info).
* Handle WC -> WC 'copy'/'move' operations. (dlr)
http://subversion.tigris.org/merge-tracking/func-spec.html#wc-wc-copy-move
Update (2007/04/23): Discussion with some Subversion dev Googlers
indicates that we should purposely break command-line UI
compatibility here, and instead require an explicit option to
avoid contacting the repos.
* Account for merge info differences for switched directories when
gathering and setting merge info. (pburba)
* Merging to out of date target can lead to corrupt merge info,
issue #2786.
* Support --depth option for merge: Limit search for children with merge
info to depth and set appropriate merge info at depth.
* Handle sparsely-populated directories, or portions of a tree not
checked out due to lack of authorization.
* Inheritance of merge info throug sparsely-populated directories
could potentially be handled via explicit merge info (e.g. to
avoid recording merge info for paths not checked out).
* There's little we can do about paths not checked out because of
insufficient authorization. Since the client isn't allowed to
know these paths exist, we can't avoid potentially inherited merge
info!
Phase 2: Post 1.5.0
-------------------
Implement auditing/reporting and other high-level features.
* Add some set of svnmerge.py-like commands for merge info
auditing/editing to the 'svn' command-line binary.
* Discuss the following command set on the dev list (as just a
jumping-off point):
avail Show unmerged revisions available for PATH as a revision list
--all show both available and blocked revisions (aka ignore
blocked revisions)
--diff show corresponding diff instead of revision list
--log show corresponding log history instead of revision list
block Block revisions within PATH so that they disappear from the
available list
integrated Show merged revisions available for PATH as a revision list
--diff show corresponding diff instead of revision list
--log show corresponding log history instead of revision list
merge
--record-only do not perform an actual merge of the changes, yet record
that a merge happened (likely phase 1?)
unblock Revert the effect of 'block'
* Write up outcome in func-spec.html.
* Account for reflected revisions when performing cyclic merges. For
example: trunk is branched, then modified, and the branch is brought
up to date with trunk in a manner which requires some conflict
resolution (e.g. additional changes on top of the revisions merged),
then the branch is modified, then the branch is merged to the trunk.
To avoid repeated merging of changes to trunk, only the modification
to the branch should be applied to trunk. That is, both the changes
from the conflict resolution performed after the merge from trunk to
branch (but not the revisions from the merge itself), plus the
additional change on the branch, should be merged back to trunk.
To accomplish this, we need to be able to be able to:
* Identify revisions which are commits of merges.
* For those revisions, differentiate between changes from revisions
already reflected by (e.g. present in) the target, and additional
changes which were not part of a merge.
Typically, VC systems handle this by having two parents for a change
set, and applying graph algorithms to handle the mechanics of
determining what to merge. See the following thread for more details:
http://subversion.tigris.org/servlets/ReadMsg?list=dev&msgNo=127570
* Add commutative author and revision reporting to 'svn blame'. (hwright)
* Improve heuristics for grokking the source URL parameter to the
'svn merge -cN URL' command. See the comments inlined into the
svn_client__suggest_merge_sources() implementation for details.
* Add command-line option for suggesting a merge source URL for use by
the 'svn merge -cN URL' command (e.g. 'svn merge --suggest-source').
* Expose the libsvn_client API for merging arbitrary revision ranges
('-c 3,5,7' or '-r 2:3,9:12') via the command-line client's UI.
* Handle three-way merges (e.g. 'svn merge URL1 URL2 WC_TARGET').
We'll likely need to use a different method of calculating the set
of revision ranges to merge than we do for a straight single repos
URL -> WC merge.
We'll need to account for the WC target's mergeinfo, probably when
calculating the differences between URL1 to URL2, since we won't
have access to the individual deltas represented by the diff when
merging the changes into the WC. If we rev'd the ways deltas came
down through the editor, we might be able to account for the merge
info on the client-side instead.
This is responsible for the failure of merge test #19, which fails
because the HEAD revision is used for both URLs, which upon
retrieving the same revnum for each URL appears to the new 'merge'
logic as neither a merge nor a revert, and is thus considered a
no-op.
* As a first cut, punt and restore the code from trunk for 3-way
merges to keep the complexity of the 'merge' logic from getting
out of hand.
* A better solution requires that either the client or server know
the merge info for both the WC and repos. This would be
implemented by transfering the merge info for the versioned
sub-tree(s) involved in the merge to or from the repository via a
(new?) RA operation, allowing the calculation of which merges
remain. The plan is to do this processing on the server-side, an
unfortunate difference from the more typical 'merge -rX:Y' style
of operation (which will be kept client-side to offload more
processing from the server).
* Implement remaining items from www/merge-tracking/requirements.html.