There are many different uses for branching and svn merge, and this section describes the most common.
Version control is most often used for software development, so here's a quick peek at two of the most common branching/merging patterns used by teams of programmers. If you're not using Subversion for software development, feel free to skip this section. If you're a software developer using version control for the first time, pay close attention, as these patterns are often considered best practices by experienced folk. These processes aren't specific to Subversion; they're applicable to any version control system. Still, it may help to see them described in Subversion terms.
Most software has a typical life cycle: code, test, release, repeat. There are two problems with this process. First, developers need to keep writing new features while quality assurance teams take time to test supposedly stable versions of the software. New work cannot halt while the software is tested. Second, the team almost always needs to support older, released versions of software; if a bug is discovered in the latest code, it most likely exists in released versions as well, and customers will want to get that bug fix without having to wait for a major new release.
Here's where version control can help. The typical procedure looks like this:
Developers commit all new work to the
            trunk.  Day-to-day changes are committed to
            /trunk: new features, bug fixes, and
            so on.
The trunk is copied to a
            “release” branch.  When the team
            thinks the software is ready for release (say, a 1.0
            release), /trunk might be copied to
            /branches/1.0.
Teams continue to work in
            parallel.  One team begins rigorous testing of
            the release branch, while another team continues new work
            (say, for version 2.0) on /trunk.  If
            bugs are discovered in either location, fixes are ported
            back and forth as necessary.  At some point, however, even
            that process stops.  The branch is “frozen”
            for final testing right before a release.
The branch is tagged and
            released.  When testing is complete,
            /branches/1.0 is copied to
            /tags/1.0.0 as a reference
            snapshot.  The tag is packaged and released to
            customers.
The branch is maintained over
            time.  While work continues
            on /trunk for version 2.0, bug fixes
            continue to be ported from /trunk to
            /branches/1.0.  When enough
            bug fixes have accumulated, management may decide to do a
            1.0.1 release: /branches/1.0 is
            copied to /tags/1.0.1, and the tag
            is packaged and released.
This entire process repeats as the software matures: when the 2.0 work is complete, a new 2.0 release branch is created, tested, tagged, and eventually released. After some years, the repository ends up with a number of release branches in “maintenance” mode, and a number of tags representing final shipped versions.
A feature branch is the sort of
        branch that's been the dominant example in this chapter (the
        one you've been working on while Sally continues to work on
        /trunk).  It's a temporary branch created
        to work on a complex change without interfering with the
        stability of /trunk.  Unlike release
        branches (which may need to be supported forever), feature
        branches are born, used for a while, merged back to the trunk,
        and then ultimately deleted.  They have a finite span of
        usefulness.
Again, project policies vary widely concerning exactly
        when it's appropriate to create a feature branch.  Some
        projects never use feature branches at all: commits to
        /trunk are a free-for-all.  The
        advantage to this system is that it's simple—nobody
        needs to learn about branching or merging.  The disadvantage
        is that the trunk code is often unstable or unusable.  Other
        projects use branches to an extreme: no change is
        ever committed to the trunk directly.
        Even the most trivial changes are created on a short-lived
        branch, carefully reviewed, and merged to the trunk.  Then
        the branch is deleted.  This system guarantees an
        exceptionally stable and usable trunk at all times, but at
        the cost of tremendous process overhead.
Most projects take a middle-of-the-road approach.  They
        commonly insist that /trunk compile and
        pass regression tests at all times.  A feature branch is
        required only when a change requires a large number of
        destabilizing commits.  A good rule of thumb is to ask this
        question: if the developer worked for days in isolation and
        then committed the large change all at once (so that
        /trunk were never destabilized), would it
        be too large a change to review?  If the answer to that
        question is “yes,” the change should be
        developed on a feature branch.  As the developer commits
        incremental changes to the branch, they can be easily reviewed
        by peers.
Finally, there's the issue of how to best keep a feature branch in “sync” with the trunk as work progresses. As we mentioned earlier, there's a great risk to working on a branch for weeks or months; trunk changes may continue to pour in, to the point where the two lines of development differ so greatly that it may become a nightmare trying to merge the branch back to the trunk.
This situation is best avoided by regularly merging trunk changes to the branch. Make up a policy: once a week, merge the last week's worth of trunk changes to the branch.
When you are eventually ready to merge the
        “synchronized” feature branch back to the trunk,
        begin by doing a final merge of the latest trunk
        changes to the branch.  When that's done, the latest versions
        of branch and trunk are absolutely identical except for
        your branch changes.  You then merge back with
        the --reintegrate option:
$ cd trunk-working-copy $ svn update Updating '.': At revision 1910. $ svn merge --reintegrate ^/calc/branches/mybranch --- Merging differences between repository URLs into '.': U real.c U integer.c A newdirectory A newdirectory/newfile U . …
Another way of thinking about this pattern is that your weekly sync of trunk to branch is analogous to running svn update in a working copy, while the final merge step is analogous to running svn commit from a working copy. After all, what else is a working copy but a very shallow private branch? It's a branch that's capable of storing only one change at a time.