- Project tools
-
-
- Announcements
- Additional Resources
-
- How do I...
-
| Category |
Featured projects |
| scm |
Subversion,
Subclipse,
TortoiseSVN,
RapidSVN
|
| issuetrack |
Scarab |
| requirements |
xmlbasedsrs |
| design |
ArgoUML |
| techcomm |
SubEtha,
eyebrowse,
midgard,
cowiki |
| construction |
antelope,
scons,
frameworx,
build-interceptor,
propel,
phing
|
| testing |
maxq,
aut
|
| deployment |
current |
| process |
ReadySET |
| libraries |
GEF,
Axion,
Style,
SSTree
|
| Over 500 more tools... |
|
Merge Tracking Requirements and Use Cases
This document details Subversion's merge
tracking requirements and their supporting use cases, the majority
of which are driven by Subversion's Developer and Merge Meister
users. A few outliers are driven by SCM automation.
Merging
Repeated Merge
Track which changesets have been applied where, so users can
repeatedly merge branch A to branch B without having to remember the
last range of revisions ported. This would also track
changeset cherry picking done by users,
so we don't accidentally re-merge changesets that are already applied.
This is the problem that svk
and arch claim to
have already solved, what they're calling star-merge
(although svk does not support cherry-picking in a sense compatible
with repeated merge).
Cherry Picking
Merge of one or more individual changesets, or changes from a
changeset (e.g. to two out of three files), from branch A into branch
B (as opposed to merge of all previously unmerged changes).
This sometimes involves manual adjustment of a change merged from
branch A into a WC for branch B before the change is committed to the
repository, or manual application of a
changeset from branch A to the WC (e.g. not using svn
merge). Regardless of the merge method used, Subversion must
provide a way to indicate that the change(s)
have been merged into branch B.
Additionally, it's important to be able to cherry pick changes in
multiple different directions. For example, if you create a release
branch B by copying the trunk you should be able to both forward port
changes made on B into trunk and backport changes made on trunk into B
without confusing the merge tracking algorithm. (This problem is
harder when you choose to cherry-pick a change from one branch to
another that you had previously cherry-picked in the other direction;
Subversion may not support this perfectly.)
Use may be predicated on information from the Show Changesets
Available for Merge feature (Auditing
section).
Track Renames in Merge
svn merge needs to handle renames better. This
requires true
rename support.
Edit foo.c on branch A. Rename foo.c to bar.c on branch B.
- Try merging the branch A edit into a working copy of branchB:
svn merge will skip the file, because it can't find
it.
- Conversely, try merging branch B rename to branch A:
svn
merge will delete the 'newer' version of foo.c and add bar.c,
which has the older text.
Problem #2 stems from the fact that we don't have true
renames, just copies (with history) and deletes. That's not
fixable without a FS schema change, and (probably) a libsvn_wc
rewrite.
It's not clear what it would take to solve problem #1. See the
discussion about our rename woes, and the relationship to merge
tracking.
Record Manual Merge
Allow changesets to be marked as merged, effectively a way to
manipulate the merge memory on target for a given merge source. This
is related to -- but not semantically equivalent to -- the revision blocking concept.
Fundamentally, the use case is to support merge tracking of a
changeset which is sufficiently different when ported to a different
branch that use of svn merge is no longer appropriate.
Examples scenarios include:
- The actual change you want to apply to branch has no overlap
with its incarnation on the source branch, yet is conceptually
equivalent.
- Only a subset of a changeset warrants application.
- The branch content has drifted far enough apart to make
automatic merging impossible (e.g. excessive merge conflicts are
generated).
Use may be predicated on information from the Show Changesets
Available for Merge feature (Auditing
section). Use supports Cherry
Picking.
Rollback Merge
Undo a merge and/or associated tracking meta data. Necessary for
both automated and manual merges.
Use may be predicated on information from the Show Changesets
Available for Merge and Show Changesets Already Merged
features (Auditing section).
Block/Unblock Changeset
Protect revisions of a source which should never be merged from
accidental merging.
This includes both blocking merging of specific revisions into a
path, and blocking merging of a specific revision to any path.
Properties
Changes to arbitrary properties set on a versioned resource should
be mergable exactly as entries within a directory (e.g. add, deleted,
etc.), or content in a file (see repeated
merge).
Subversion's revision properties (sometimes referred to as
revprops) need not be handled.
Merge Previews
Merge previews are dry runs that show conflicts and "non-trivial,
non-conflicting" (NTNC) changes in advance. These previews should be
exportable and parseable. (From the distributable resolution item in the summit summary.)
SCM Automated Merge
The ability to automate merges (e.g. from a stable branch to a
development branch), including interfaces for resolving conflicts and
handling other errors, is important. Merge Meisters
who do multi-thousand file merges stress this.
Distributability of Merge Resolution
The mechanism for resolving conflicts in a merge should be
distributable across N developers. Meeting this requirement might
mean a departure for Subversion, since it implies that merge results
are not just stored in one working copy, but are somehow available on
the server side. (From the distributable resolution item in the summit summary.)
Auditing
Merge tracking must be audit-friendly, supporting some basic forms
of reporting which allow for discovery of at least the following types
of information.
Additionally, merge info should be transitive. Often we merge a
bunch of changes to a backport branch, tweak them there, then later
merge the branch into a release line. Later queries of the release
line should show that the original revisions are present, and queries
of the original revisions should show that they went to the release
line as well as the backport branch.
Changeset Merge Availability
- Show Changesets Available for Merge
- Support query of any path (file, directory, or symlink) to find
out what changes (revisions) for a merge source haven't been merged
under it. For files, "under" just means "into".
- Show Changesets Already Merged
- Support query any path (file, directory, or symlink) to find out
what changes (revisions) have been merged under it. For files,
"under" just means "into".
- Show Changesets Blocked from Merging
- If you've blocked some set
of revisions from being merged from branch B into some destination
(e.g. trunk), you should be able to discover which revisions have
been blocked.
Find Changeset
- Merged From info for Changeset and/or Path
- If you merged rN from branch A into branch B in rM, it should be
possible to query rM -- or branch B at or after rM, but before it's
been moved or deleted -- to ask what sources it has been merged
from, and the answer set should contain A at rN.
- Merged To info for Changeset and/or Path
- If you merge rN from branch A into branch B in rM, it should be
possible to query rN -- or branch A at or after rN, but before it's
been moved or deleted -- to ask what destinations it has been merged
to, and the answer set should contain B at rM.
- Find Paths containing Specific Incarnation of Versioned Resource
- It should be easy to discover all the paths at which a
particular node revision (i.e., unique versioned file entity)
exists, especially in a given revision. In other words, this is the
"what branches does this exact version of this file exist in"
problem, often requested by so-called enterprise-level users.
Blue sky, we may want to enhance the reporting capabilities to
allow retrieval of a log of changes to merge tracking information.
This log should list both when the merges were applied, and when the
merge meta data was updated.
Commutative Author and Revision Reporting for Merged Changesets
The ability to report either/both the actual committer and revision
number of a changeset, and/or the original author and revision
number. This applies to any operations which report an author,
including:
For example:
- If you merge rN into a branch B, and rN was committed by author
A, then
svn blame should provide the ability to show
the changed lines in B as last touched by A, even if the merge was
committed by you and you are not A. This must also work when
merging a range of revisions with different authors.
- If you merge rN into a branch B, and rN was committed by author
A, then
svn log -rN should show both the original
author A, and the author who merged the change.
The UI and API for toggling this behavior should be consistent
across operations.
Miscellaneous
Allow for Dump/Load
Whatever solution is chosen must play well with svnadmin
dump and svnadmin load. For example, the metadata
used to store merge tracking history must not be stored in terms of
some filesystem backend implementation detail (e.g.
"node-revision-ids") unless, perhaps, those IDs are present for all
items in the dump as a sort of "soft data" (which would allow them to
be used for "translating" the merge tracking data at load time, where
those IDs would be otherwise irrelevant). See issue
1525 about user-visible entity IDs.
User Interface Ease in Common Cases
(This was one of the points made at the EuroOSCON 2005 Version Control BOF session.)
The interface for common-case merges should be easy. Currently it
is not. For example, a very common case is merging all previously
unmerged changes from trunk to branch (more formally, from a source
line to a descendant destination line). Today, one must type
svn merge -rX:Y URL WC. But why
can't the dest just remember what has been merged from that src before
and do the right thing? Then one could type
svn merge SRC DST. Or better yet,
branches could remember where they come from, and one could just type
svn merge SRC, or
svn merge DST, depending on whether one wants a
push or pull interface. (It was pointed out that SVK does remember
these things; if someone familiar with the SVK interface wants to put
an example transcript here, that would be great.)
Here is the svk command transcript:
A branch creation by:
svk copy //project/trunk //project/branch-B
(or mirroring an existing subversion repository containing such branch)
To merge from trunk to branch-B:
svk smerge //project/trunk //project/branch-B, or
svk smerge --to //project/branch-B, or
svk pull //project/branch-B
To merge from branch-B back to trunk:
svk smerge //project/trunk //project/branch-B, or
svk smerge --from //project/branch-B, or
svk push //project/branch-B
There is also a -I flag in smerge to merge changes
revision-by-revision. Push is by default with the option, and
pull is not.
Another common case is porting a single change from one line to
another. This currently requires -r<X-1>:X syntax,
but Subversion 1.4 will include the -c option (introduced
in r17054), so users will no longer need to perform this menial
arithmetic. However, Subversion 1.4 will still require the URL of the
merge source to be specified; a merge tracking solution that eases
common cases would obviate the need for the user to supply the URL
when a single change is ported from a branch's ancestor line.
svk merge also supports -c N flag which is
-rN-1:N.
Compatibility with older Subversion clients
- Older Subversion clients should still be able to commit merges on new
repositories.
- Repository administrators should be able to control whether older clients
(which do not support merge tracking) can commit changes to specific (e.g.
branch or tag) subdirectories.
Versioning
Merge tracking information should be maintained for all versions of
files in a repository. Thus, if you create a copy of an old version of
a branch, the merge tracking information will still be accurate.
Changes to merge tracking information should be versioned,
therefore allowing tracking and auditing of changes to merge
tracking data.
Authorization
Repository administrators should be able to control whether merge
tracking information can be committed by specific users or to specific
directories.
Repository administrators should be able to control whether changes
can be committed without associated merge-tracking information. Using
this feature, a repository administrator could enforce (for example)
that all changes must be committed to trunk before they are merged to
a release branch.
$Date: 2007-12-04 15:04:07 -0800 (Tue, 04 Dec 2007) $
|