One of the features of version control systems is the ability
to isolate changes onto a separate line of development.
This line is known as a branch.
Branches are often used to try out new features without
disturbing the main line of development with compiler
errors and bugs. As soon as the new feature is stable enough
then the development branch is merged
back into the main branch (trunk).
Another feature of version control systems is the ability
to mark particular revisions (e.g. a release version),
so you can at any time recreate a certain build or
environment. This process is known as tagging.
Subversion does not have special commands for branching
or tagging, but uses so-called “cheap copies”
instead. Cheap copies are similar to hard links in Unix, which means
that instead of making a complete copy in the repository, an internal
link is created, pointing to a specific tree/revision. As a result
branches and tags are very quick to create, and take up almost
no extra space in the repository.
4.19.1. Creating a Branch or Tag
If you have imported your project with the recommended
directory structure, creating a branch or tag version is very simple:
Select the folder in your working copy which you want to copy
to a branch or tag, then select the command
→ .
The default destination URL for the new branch
will be the source URL on which your working copy is based.
You will need to edit that URL to the new path for your branch/tag.
So instead of
http://svn.collab.net/repos/ProjectName/trunk
you might now use something like
http://svn.collab.net/repos/ProjectName/tags/Release_1.10
If you can't remember the naming convention you used last time,
click the button on the right to open the repository browser
so you can view the existing repository structure.
Now you have to select the source of the copy. Here you have
three options:
- HEAD revision in the repository
The new branch is copied directly in the repository
from the HEAD revision. No data needs to be transferred
from your working copy, and the branch is created
very quickly.
- Specific revision in the repository
The new branch is copied directly in the repository
but you can choose an older revision. This is useful
if you forgot to make a tag when you released your
project last week. If you can't remember the revision
number, click the button on the right to show the
revision log, and select the revision number from
there. Again no data is transferred from your working
copy, and the branch is created very quickly.
- Working copy
The new branch is an identical copy of your local
working copy. If you have updated some files to an
older revision in your WC, or if you have made local
changes, that is exactly what goes into the copy.
Naturally this sort of complex tag may involve
transferring data from your WC back to the repository
if it does not exist there already.
If you want your working copy to be switched to the newly created
branch automatically, use the
Switch working copy to new branch/tag checkbox.
But if you do that, first make sure that your working copy does not
contain modifications. If it does, those changes will be merged into
the branch WC when you switch.
If your working copy has other projects included with
svn:externals
properties, those externals will
be listed at the bottom of the branch/tag dialog. For each external,
the target path, the source URL and the revision is shown. The revision
of the external is determined from the working copy, which means it
shows the revision that external actually points to.
If you want to make sure that the new tag always is in a consistent
state, check all the externals to have their revisions fixed to
their current working copy revision. If you don't check the externals
and those externals point to a HEAD revision which might change
in the future, checking out the new tag will check out that HEAD
revision of the external and your tag might not compile anymore.
So it's always a good idea to set the externals to an explicit revision
when creating a tag.
If externals are set to an explicit revision when creating a branch or
tag, TortoiseSVN automatically changes the svn:externals
property. When the branch/tag is created from HEAD or a specific revision
in the repository, TortoiseSVN first creates the branch/tag, then adjusts
the properties. This will create additional commits for each property.
When the branch/tag is created from the working copy, the properties
are modified first, then the branch/tag is created and then the properties
are changed back to their original value.
Press OK to commit the new copy to the
repository. Don't forget to supply a log message. Note that the
copy is created inside the repository.
Note that unless you opted to switch your working copy to the newly
created branch, creating a Branch or Tag does not
affect your working copy. Even if you create the branch from your WC,
those changes are committed to the new branch, not to the trunk, so your
WC may still be marked as modified with respect to the trunk.
4.19.2. Other ways to create a branch or tag
You can also create a branch or tag without having a working copy.
To do that, open the repository browser. You can there drag folders
to a new location. You have to hold down the Ctrl
key while you drag to create a copy, otherwise the folder gets moved,
not copied.
You can also drag a folder with the right mouse button. Once you
release the mouse button you can choose from the context menu whether
you want the folder to be moved or copied. Of course to create a branch
or tag you must copy the folder, not move it.
Yet another way is from the log dialog. You can show the log dialog
for e.g. trunk, select a revision (either the HEAD revision at the
very top or an earlier revision), right click and choose
.
4.19.3. To Checkout or to Switch...
...that is (not really) the question. While a checkout downloads
everything from the desired branch in the repository to your working
directory,
→
only transfers the changed data to your
working copy. Good for the network load, good for your patience. :-)
To be able to work with your freshly generated branch or tag you
have several ways to handle it. You can:
→
to make a fresh checkout in an empty folder.
You can check out to any location on your
local disk and you can create as many working copies
from your repository as you like.
Switch your current working copy to the
newly created copy in the repository. Again select the
top level folder of your project and use
→
from the context menu.
In the next dialog enter the URL of the branch you just created.
Select the
Head Revision
radio button and click on
OK.
Your working copy is switched to the new branch/tag.
Switch works just like Update in that it never discards your
local changes. Any changes you have made to your working copy
which have not yet been committed will be merged when you
do the Switch. If you do not want this to happen then you
must either commit the changes before switching, or revert
your working copy to an already-committed revision (typically HEAD).
If you want to work on trunk and branch, but don't want
the expense of a fresh checkout, you can use Windows Explorer
to make a copy of your trunk checkout in another folder, then
→
that copy to your new branch.
Although Subversion itself makes no distinction between tags
and branches, the way they are typically used differs a bit.
Tags are typically used to create a static snapshot of the
project at a particular stage. As such they are not normally
used for development - that's what branches are for, which
is the reason we recommended the
/trunk /branches /tags
repository structure in the first place. Working on a tag
revision is not a good idea, but
because your local files are not write protected there is
nothing to stop you doing this by mistake.
However, if you try to commit to a path in the repository
which contains /tags/
, TortoiseSVN will
warn you.
It may be that you need to make further changes to a
release which you have already tagged. The correct way
to handle this is to create a new branch from the tag
first and commit the branch. Do your Changes on this
branch and then create a new tag from this new branch, e.g.
Version_1.0.1
.
If you modify a working copy created from
a branch and commit, then all changes go to the new
branch and not the trunk.
Only the modifications are stored.
The rest remains a cheap copy.