Review of chapter 4 - Branching and Merging

Julian Foad julianfoad at
Tue Mar 18 21:13:53 CDT 2008

Dear book authors,

Here's a review of the merging aspects of chapter 4 (and related entries in
ch09 reference), including input from Paul Burba.

Branching and Merging (ch04)

Keeping a Branch in Sync

On first introducing the basic merge command, reinforce that "svn merge URL"
means to merge changes *from* URL into WC.

After reintegrating, say that I can continue working on the branch and catch
up and reintegrate again, or I can delete the branch, or leave it there and
make that decision later. (Paul noticed a bug in that self-referential
mergeinfo is currently created by these further catch-up and reintegrate
cycles; he will look into fixing this.)

The "reintegrate" option is explained well in terms of being the right way to
merge changes back to trunk in the example scenario. We need to explain also
the real meaning and distinction of the two forms of merge so that users can
see whether and how they can be applied to other scenarios. For example, if I
create a sub-feature branch B2 off feature branch B, can I then sync B2 from
trunk, from B, or from both trunk and B2 at arbitrary times, and can I then
reintegrate B2 to B, or B2 to trunk, or both or neither?

Say that "reintegrate" makes trunk be exactly like branch, by applying the
diff necessary to make it so.

Be stronger on the need for WC being up to date and clean. (Recommend using
"svn up" to ensure or "svnversion" to verify that WC is single-revision.) For
the "reintegrate" case, suggest replacing the text "However you get a trunk
working copy..." with something like:

  "However you get a trunk working copy, remember that it must be fully
updated (no mixed-revision WCs allowed) and have no local edits. If your
working copy isn't “clean” in these ways, svn merge --reintegrate won't work
and will return an error."

For the normal "merge" command, what can we say about what happens if you
don't follow the recommendations on WC being up to date and clean?

Syntax (Full Disclosure)

Examples box: first example (a 2-URL merge) is potentially a non-tracking
merge, depending on the relationship between the sources. Mention this, with a
reference to the new "Merges that are Not Tracked" section.

Merges that are Not Tracked

Create this new section, to mention at least:
  - foreign-repository merges
  - arbitrary diff-and-apply merges due to specifying two unrelated sources
  - merges requested by "--ignore-ancestry"  - reverse-merging a change from a
path's own history (Note that it does work, but there is currently no way to
record the fact that it has been done.  This really gets into the whole idea
of a path's 'natural' history and how that is taken into a account *along
with* svn:mergeinfo...likely a topic too dense for the book?)

Resurrecting Deleted Items

This section is not closely related to merging; merging is just one of the
ways to resurrect deleted items. Consider moving this section out of the main
flow of information about merging. Insert a brief reference to it in the
"Undoing Changes" section. See also the "Data Lifetimes" section which repeats
this somewhat.

Blocking Changes

This topic is not so much a primary topic but rather a side-bar on the extent
to which you can push Subversion.

By "faking" a merge (e.g. with --record-only or by resolving all changes as
--accept=mine), we can prevent particular revisions from being merged to the
destination branch. This can be useful on a branch that is never intended to
be merged back to its parent, such as a "release" branch.

This is not a proper "blocking" feature because the intent is not recorded.
What is recorded is just the same as if we'd performed the merge, but then
adjusted the resulting text back to what it was before, and this is
indistinguishable from the kind of editing we might have done in resolving a
conflict. As a consequence, if the branch is reintegrated to its parent then
the blocked changes will be removed from the parent.

Don't even suggest modifying the property with "propset".

Merge-sensitive Logs and Annotations

Log: does "-g" show all branches through which a given change has been merged
to reach the target branch, or just the nearest, or just the most distant?

Blame: same question.

Do the log and blame APIs allow the merges via intermediate branches to be

Noticing or Ignoring Ancestry

Does "diff" really ignore ancestry by default, even when used in the
merge-like manner of "svn diff -r10:20 foo at 20"?

Mention that "diff" behaves like this *unless* the "--notice-ancestry" option
is given.

Data Lifetimes

Repeats the "Resurrecting Deleted Items" section somewhat.


"Branches are cheap. So use them liberally!" - No! They're cheap to create, so
you shouldn't hesitate to create one when needed, but "use them liberally"
invites trouble.


How To Edit svn:mergeinfo

Syntax. Inheritance/elision. (Paul is working on a document describing this.)

Is there any caveat necessary for editing mergeinfo for an uncommitted merge
before resolving conflicts - e.g. if you edit mergeinfo on the root of your WC
and then resolve conflicts on some children, are there any circumstances under
which Subversion might invalidate your local corrections? We believe there are
no such surprises here, but it would be nice if somebody else could confirm.

Under what conditions is it safe to correct mergeinfo in a later commit after
the fact? - e.g. if you commit the manual merge (without mergeinfo) in r10,
then correct the mergeinfo in r20, can we say that everything will work
properly thereafter as long as you never merge in or out of that branch in a
way that splits the revision range 10-20?


Reference (ch09)

  mention svn:mergeinfo

  --use-merge-history: wrongly mentions "svn copy/move" which don't take this

svn merge:
  mention --reintegrate

svn mergeinfo:
  mention --from-source


- Julian

More information about the svnbook-dev mailing list