Our current help texts explain syntax of commands quite well,
but they don't really explain the semantics. This makes svn help
fairly useless for people who just want to get going with their
first steps in Subversion.
The Subversion book on the other hand explains the semantics very well,
but it literally takes pages upon pages for doing so. It is quite
detailed and often provides too much information (and verbiage) for
people who just want to get going. Many people end up coming to the #svn
IRC channel looking for help, only to be told to read the book anyway.
I think "svn help" should cover more middle ground. To illustrate what
I'd like to do, I've rewritten the help text for "svn merge", because
its current form is a particularly bad example of virtually useless help
text for people who just want to get started.
In Subversion courses and workshops I give during my work at elego,
I usually introduce the merge functionality of Subversion based on
use cases people will need to deal with. I've found that people have
little difficulty working with "svn merge" after being given a short
use-case focused introduction.
So the proposed help text below centers around the most common use cases.
It is longer than the old help text, but leaves out many details covered
in the book. Note that I've also changed the order in which the various
merge types are presented. The current help text starts out explaining
the syntax of 2-URL merges, which are rarely needed these days, and the
most difficult to understand at the semantic level.
I'd like to revise help texts for other subcommands in a similar manner.
Eventually, I'd like svn help will point out in which order the subcommand
help texts can be read to receive a small introductory tutorial on svn.
But it would also refer people to the book for more information.
Of course, good texts present just the right amount of information
with as little words as possible. I don't think the below text is as
good as it can get yet, but I got tired of tweaking it for today.
Thoughts? Comments?
Thanks,
Stefan
merge: Apply the differences between two sources to a working copy path.
usage: 1. merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [TARGET_WCPATH]
2. merge --reintegrate SOURCE[@REV] [TARGET_WCPATH]
3. merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]
1. The first form is called a "sync" merge, or "cherry-pick" merge:
svn merge [-c M[,N...] | -r N:M ...] SOURCE[@REV] [TARGET_WCPATH]
A sync merge is used to merge into a branch any unmerged changes
made on its immediate ancestor branch.
A cherry-picking merge is used to merge into a branch selected
changes made on another branch.
In both cases, SOURCE is a URL. If REV is specified, it is used as
the peg revision for SOURCE, i.e. SOURCE is looked up in the repository
at revision REV. If REV is not specified, the HEAD revision is assumed.
The source can also be specified as working copy path, in which case
the URL of the merge source is derived from the working copy.
TARGET_WCPATH is a working copy of the branch the changes will
be applied to.
'-r N:M' specifies a revision range to be merged. The difference
between SOURCE_at_REV as it existed at revision N, and SOURCE_at_REV at
it existed at revision M, is merged into TARGET_WCPATH.
If no revision range is specified, the default range of 0:REV is used.
If mergeinfo within TARGET_WCPATH indicates that revisions within the
range were already merged, changes made in those revisions are not
merged again. If needed, the range is broken into multiple sub-ranges,
and each sub-range is merged separately.
If N is greater than M, the range is a "reverse range". Such a range
can be used to undo changes made to SOURCE between revisions N and M.
'-c M' is equivalent to the range '-r <M-1>:M'.
'-c -M' does the reverse: '-r M:<M-1>'.
Multiple '-c' and/or '-r' options may be specified, and mixing of
forward and reverse ranges is allowed.
- Sync Merge Example -
A feature is being developed on a branch called "feature".
The feature branch is regularly synced with trunk to keep up with
changes made there.
feature +------------------------o-----
/ ^
/ /
/ .............../
trunk ------+------------L--------------R------
r100 r200
In the above diagram, L marks the "left" side of the merge (trunk_at_100),
and R marks the "right" side of the merge (trunk_at_200).
The difference between the left and right side is merged into the target.
To perform the merge, check out a working copy of the feature branch
and run the following command in the top-level directory of the working
copy:
svn merge ^/trunk
The default revision range is -r0:HEAD, so any unmerged changes will
be merged. To merge only a specific range of revisions, specify a
revision range:
svn merge -r100:200 ^/trunk
- Cherry-picking Merge Example -
A bug has been fixed on trunk on revision 50. This fix needs to
be released in the next release of the line of 1.x releases.
The fix needs to be merged from the trunk into the release branch.
1.x-release +-----------------------o-----
/ ^
/ |
/ |
trunk ------+--------------------------LR-----
r50
In the above diagram, L marks the left side of the merge (trunk_at_49)
and R marks the right side of the merge (trunk_at_50).
The difference between the left and right side is merged into the target.
To perform the merge, check out a working copy of the feature branch
and run the following command in the top-level directory of the working
copy:
svn merge -c50 ^/trunk
If several commits to trunk were related to the fix, multiple revisions
to can be merged:
svn merge -c50,54,60 ^/trunk
2. The second form is called a "reintegrate merge":
svn merge --reintegrate SOURCE[@REV] [TARGET_WCPATH]
SOURCE is the URL of a branch to be merged back into (usually) its
immediate ancestor branch. If REV is specified, it is used as the peg
revision for SOURCE, i.e. SOURCE is looked up in the repository at
revision REV. If REV is not specified, the HEAD revision is assumed.
TARGET_WCPATH is a working copy of the branch the changes will
be applied to.
The source can also be specified as working copy path, in which case
the URL of the merge source is derived from the working copy.
- Reintegrate Merge Example -
A feature has been developed on a branch called "feature".
Work on the feature has completed and it should be merged back
into the trunk.
The feature branch was last synced with its immediate ancestor,
the trunk, in revision X. So the difference between trunk_at_X and
feature_at_HEAD contains the complete set of changes related to the feature,
and no other changes. This diff is applied to the trunk.
feature +-------------------------------R
/ . \
/ .............. \
/ . v
trunk ------+--------------------L------------------o
rX
In the diagram above, L marks the left side of the merge (trunk_at_X),
and R marks the right side of the merge is (feature_at_HEAD).
The difference between the left and right side is merged into the target.
To perform the merge, check out a working copy of the trunk, and run
the following command in the top-level directory of the working copy:
svn merge --reintegrate ^/feature
To prevent unnecessary merge conflicts, the reintegrate merge requires
that TARGET_WCPATH is not a mixed-revision working copy, and has no
local modifications, and has no switched subtrees. It also requires
that all changes which were merged into the reintegrate source have
also been merged into the target.
After the reintegrate merge, the feature branch cannot be synced to
the trunk again without merge conflicts. If further work must be done
on the feature branch, it should be deleted and then re-created.
3. The third form is called a "2-URL merge":
svn merge SOURCE1[@N] SOURCE2[@M] [TARGET_WCPATH]
Two source URLs are specified, together with two revisions N and M.
The two sources to be compared at the specified revisions, and the
difference is applied to TARGET_WCPATH, which is a path to a working
copy of another branch.
The revisions default to HEAD if omitted.
If TARGET_WCPATH is omitted, a default value of '.' is assumed, unless
the sources have identical basenames that match a file within '.';
In which case, the differences will be applied to that file.
The sources can also be specified as working copy paths, in which case
the URLs of the merge sources are derived from the working copies.
This is the most flexible type of merge, but also the most difficult
to use. It can be used to merge the differences between two (possibly
ancestrally unrelated) branches into a working copy of another branch.
This type of merge should be used very carefully because the probability
of merge conflicts is quite high. If possible, avoid doing 2-URL merges.
- 2-URL Merge Example -
A feature has been developed on a branch called "feature".
Development for the upcoming 3.0 release has happened in parallel on
the "3.x-release" branch. There is huge demand for having the feature
in the upcoming 3.0 release, so it has been decided to merge it into the
3.x-release branch. However, the feature branch and the 3.x-release
branch are not directly related, so a 2-URL merge is needed.
The feature branch was last synced with its immediate ancestor,
the trunk, in revision 500. So the difference between trunk_at_500 and
feature_at_HEAD contains the complete set of changes related to the feature,
and no other changes. This diff is applied to the 3.x-release branch.
3.x-release +-----------------------------------o
/ ^
/ /
/ /
trunk ------+------+------------------L----- /
\ . /
\ ........... /
\ . /
feature +---------------------o-------------R
r500
In the diagram above, L marks the left side of the merge (trunk_at_500),
and R marks the right side of the merge is (feature_at_HEAD).
The difference between the left and right side is merged into the target.
To perform the merge, check out a working copy of the 3.x-release
branch and run the following command in the top-level directory
of the working copy:
svn merge ^/trunk_at_500 ^/feature
Before performing a 2-UL merge, it is a good idea to preview the changes
which will be merged. This can be done with the svn diff command:
svn diff ^/trunk_at_500 ^/feature_at_HEAD
The following applies to all types of merges:
For each merged item a line will be printed with characters reporting
the action taken. These characters have the following meaning:
A Added
D Deleted
U Updated
C Conflict
G Merged
E Existed
R Replaced
Characters in the first column report about the item itself.
Characters in the second column report about properties of the item.
A 'C' in the third column indicates a tree conflict, while a 'C' in
the first and second columns indicate textual conflicts in files
and in property values, respectively.
NOTE: Subversion will only record metadata to track the merge (mergeinfo)
if the two sources are on the same line of history -- if the first source
is an ancestor of the second, or vice-versa. This is guaranteed to be the
case when using sync merges and reintegrate merges.
The --ignore-ancestry option overrides this, forcing Subversion to regard
the sources as unrelated and not to track the merge.
Valid options:
-r [--revision] ARG : ARG (some commands also take ARG1:ARG2 range)
A revision argument can be one of:
NUMBER revision number
'{' DATE '}' revision at start of the date
'HEAD' latest in repository
'BASE' base rev of item's working copy
'COMMITTED' last commit at or before BASE
'PREV' revision just before COMMITTED
-c [--change] ARG : the change made by revision ARG (like -r ARG-1:ARG)
If ARG is negative this is like -r ARG:ARG-1
-N [--non-recursive] : obsolete; try --depth=files or --depth=immediates
--depth ARG : limit operation by depth ARG ('empty', 'files',
'immediates', or 'infinity')
-q [--quiet] : print nothing, or only summary information
--force : force operation to run
--dry-run [--dry] : try operation but make no changes
--diff3-cmd ARG : use ARG as merge command
--record-only [--ro] : merge only mergeinfo differences
-x [--extensions] ARG : Default: '-u'. When Subversion is invoking an
external diff program, ARG is simply passed along
to the program. But when Subversion is using its
default internal diff implementation, or when
Subversion is displaying blame annotations, ARG
could be any of the following:
-u (--unified):
Output 3 lines of unified context.
-b (--ignore-space-change):
Ignore changes in the amount of white space.
-w (--ignore-all-space):
Ignore all white space.
--ignore-eol-style:
Ignore changes in EOL style.
-p (--show-c-function):
Show C function name in diff output.
--ignore-ancestry [--ia] : ignore ancestry when calculating merges
--accept ARG : specify automatic conflict resolution action
('postpone', 'base', 'mine-conflict',
'theirs-conflict', 'mine-full', 'theirs-full',
'edit', 'launch')
--reintegrate [--ri] : merge a branch back into its parent branch
--allow-mixed-revisions : Allow merge into mixed-revision working copy.
Use of this option is not recommended!
Please run 'svn update' instead.
Global options:
--username ARG : specify a username ARG
--password ARG : specify a password ARG
--no-auth-cache [--nac] : do not cache authentication tokens
--non-interactive : do no interactive prompting
--trust-server-cert : accept unknown SSL server certificates without
prompting (but only with '--non-interactive')
--config-dir [--cd] ARG : read user configuration files from directory ARG
--config-option ARG : set user configuration option in the format:
FILE:SECTION:OPTION=[VALUE]
For example:
servers:global:http-library=serf
Received on 2010-10-29 17:57:45 CEST