You may have noticed by now that Subversion is extremely flexible. Because it implements branches and tags with the same underlying mechanism (directory copies), and because branches and tags appear in normal filesystem space, many people find Subversion intimidating. It's almost too flexible. In this section, we'll offer some suggestions for arranging and managing your data over time.
There are some standard, recommended ways to organize the
contents of a repository. Most people create a
trunk
directory to hold the “main
line” of development, a branches
directory to contain branch copies, and
a tags
directory to contain tag copies.
If a repository holds only one project, often people create
these top-level directories:
/
trunk/
branches/
tags/
If a repository contains multiple projects, admins typically index their layout by project. See the section called “Planning Your Repository Organization” to read more about “project roots”, but here's an example of such a layout:
/
paint/
trunk/
branches/
tags/
calc/
trunk/
branches/
tags/
Of course, you're free to ignore these common layouts. You can create any sort of variation, whatever works best for you or your team. Remember that whatever you choose, it's not a permanent commitment. You can reorganize your repository at any time. Because branches and tags are ordinary directories, the svn move command can move or rename them however you wish. Switching from one layout to another is just a matter of issuing a series of server-side moves; if you don't like the way things are organized in the repository, just juggle the directories around.
Remember, though, that while moving directories is easy to do, you need to be considerate of other users as well. Your juggling can disorient users with existing working copies. If a user has a working copy of a particular repository directory and your svn move subcommand removes the path from the latest revision, then when the user next runs svn update, she is told that her working copy represents a path that no longer exists. She is then forced to svn switch to the new location.
Another nice feature of Subversion's model is that
branches and tags can have finite lifetimes, just like any
other versioned item. For example, suppose you eventually
finish all your work on your personal branch of the
calc
project. After merging all of your
changes back into /calc/trunk
, there's
no need for your private branch directory to stick around
anymore:
$ svn delete http://svn.example.com/repos/calc/branches/my-calc-branch \ -m "Removing obsolete branch of calc project." Committed revision 474.
Recall from the previous section that if the repository location your working copy refers to is deleted, then when you try to update you will receive an error:
$ svn up Updating '.': svn: E160005: Target path '/calc/branches/my-calc-branch' does not exist
All you need to do in this situation is switch your working copy to a location that still exits:
$ svn sw ^/calc/trunk D src/whole.c U src/real.c A src/integer.c U . Updated to revision 474.
And now your branch is gone. Of course, it's not really
gone: the directory is simply missing from the
HEAD
revision, no longer distracting
anyone. If you use svn checkout,
svn switch, or svn list
to examine an earlier revision, you can still see
your old branch.
If browsing your deleted directory isn't enough, you can
always bring it back. Resurrecting data is very easy in
Subversion. If there's a deleted directory (or file) that
you'd like to bring back into HEAD
, simply
use svn copy to copy it from the old
revision:
$ svn copy ^/calc/branches/my-calc-branch@473 \ ^/calc/branches/my-calc-branch \ -m "Restore my-calc-branch." Committed revision 475.
In our example, your personal branch had a relatively
short lifetime: you may have created it to fix a bug or
implement a new feature. When your task is done, so is the
branch. In software development, though, it's also common to
have two “main” branches running side by side for
very long periods. For example, suppose it's time to release
a stable version of the calc
project to the
public, and you know it's going to take a couple of months to
shake bugs out of the software. You don't want people to add
new features to the project, but you don't want to tell all
developers to stop programming either. So instead, you create
a “stable” branch of the software that won't
change much:
$ svn copy ^/calc/trunk ^/calc/branches/stable-1.0 \ -m "Creating stable branch of calc project." Committed revision 476.
And now developers are free to continue adding
cutting-edge (or experimental) features to
/calc/trunk
, and you can declare a
project policy that only bug fixes are to be committed to
/calc/branches/stable-1.0
. That is, as
people continue to work on the trunk, a human selectively
cherrypicks bug fixes over to the stable branch. Even after the
stable branch has shipped, you'll probably continue to
maintain the branch for a long time—that is, as long
as you continue to support that release for customers. We'll
discuss this more in the next section.