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

RFC: revised text for "svn help merge"

From: Stefan Sperling <stsp_at_elego.de>
Date: Fri, 29 Oct 2010 17:57:00 +0200

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

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.