This section is from the "Version Control with Subversion" book, by Ben Collins-Sussman, Brian W. Fitzpatrick and C. Michael Pilato. Also available from Amazon: Version Control with Subversion.
The basic mechanism Subversion uses to track
changesets—that is, which changes have been merged to
which branches—is by recording data in properties.
Specifically, merge data is tracked in
the svn:mergeinfo property attached to
files and directories. (If you're not familiar with
Subversion properties, now is the time to go skim over
the section called “Properties”.)
You can examine the property, just like any other:
$ cd my-calc-branch $ svn propget svn:mergeinfo . /trunk:341-390
It is not recommended that you change the value of this property yourself, unless you really know what you're doing. (An example of this comes up in the section called “Blocking Changes”.) In general, this property is automatically maintained by Subversion whenever you run svn merge, and its value indicates which changes have already been replicated into a particular directory.
As we saw earlier, there's also a subcommand svn mergeinfo, which can be helpful in seeing not only which changesets a directory has absorbed, but also which changesets it's still eligible to receive. This gives a sort of preview of the next set of changes that svn merge will replicate to your branch.
$ svn mergeinfo .
Path: .
Source path: /trunk
Merged ranges: r341:390
Eligible ranges: r391:395
The svn mergeinfo command, by default,
looks back at the history of the thing you're querying and
tries to make a sane guess about the “source”
from which you want to be copying changes. In our prior
example, because we're querying our branch working copy, the
command assumes we're interested in receiving changes
from /trunk (since that's where our
branch was originally copied from). However, if another
coworker had a different branch going on that we wanted to
merge changes from, we could have this command tell us about
eligible changesets from that source too:
$ svn mergeinfo --from-source \
http://svn.example.com/repos/calc/branches/other-branch .
Path: .
Source path: /branches/other-branch
Merged ranges:
Eligible ranges: r360:364
Another way to get a more precise preview of a merge
operation is to use the --dry-run
option.
$ svn merge http://svn.example.com/repos/calc/trunk --dry-run U integer.c $ svn status # nothing printed, working copy is still unchanged.
The --dry-run option doesn't actually
apply any local changes to the working copy. It shows only
status codes that would be printed in a
real merge. It's useful for getting a “high
level” preview of the potential merge, for those times
when running svn diff gives too much
detail.
After performing a merge operation, but before committing the results of the merge, you can use svn diff --depth=empty /path/to/merge/target to see only the changes to the immediate target of your merge. If your merge target was a directory, only property differences will be displayed. This is a handy way to see the changes to the svn:mergeinfo property recorded by the merge operation, which will remind you about what you've just merged.
Of course, the best way to preview a merge operation is to just do it! Remember, running svn merge isn't an inherently risky thing; if you don't like the results, simply svn revert -R the changes from your working copy and retry the command with different options. The merge isn't final until you actually svn commit the results.
While it's perfectly fine to experiment with merges by running svn merge and svn revert over and over, you may run into some annoying (but easily bypassed) roadblocks. For example, if the merge operation adds a new file (i.e., schedules it for addition), then svn revert won't actually remove the file; it simply unschedules the addition. You're left with an unversioned file. If you then attempt to run the merge again, you may get conflicts due to the unversioned file “being in the way.” Solution? After performing a revert, be sure to clean up the working copy and remove unversioned files and directories. The output of svn status should be as clean (read: empty) as possible!