Branches
About branches
A branch is a separate timeline of changes that you can create by splitting off from the main line of your project’s history. On a branch, you can safely experiment or work on a new feature, and the commits that you make to that branch will not affect or break the stable state of your project (the project’s main line of history). In the meantime, the project’s main line of history can receive commits that do not affect your branch.
Generally speaking, the trunk directory, which represents the main line of
the project’s history, can also be considered a branch. What is special about
the trunk, is that it is the main branch. That is, the trunk is usually the
initial and the oldest branch in the project, from which other newer
shorter-lived branches split off.
Branches in Subversion are directories
A notable feature of Subversion is that each branch is just a directory
(folder) in the repository. Each new branch starts as a lightweight tracked
‘copy’ of some already existing branch. Typically, a user creates a new branch
as a copy of the trunk directory.
For example, after you create your first branch (let us call it
my_feature_one) as a copy of trunk, the directory structure in the
repository will look like this:
MyRepo
├── trunk
├── branches
│ └── my_feature_one
└── tags
Branches are cheap storage-wise
It is not universally known, but creating a new branch is extremely ‘cheap’ in terms of storage space required for this on the server. No matter how much data an existing branch contains, making a server-side copy of that existing branch in the repository takes up a constant and tiny amount of storage space and is a nearly instantaneous operation. This is because on the server side Subversion uses a copy-on-write approach, which shares the same underlying repository data between the original and the new branch as much as it can.
For example, even if your trunk directory contains many gigabytes of files,
creating a new branch as a copy of trunk increases the repository size on the
server only by around 1 kilobyte. Only once you commit new edits to that new
branch, the actual size of the new branch will grow, in proportion to the size
of these new branch-specific edits.
The command to create a new branch
On the command line, the syntax to create a new branch from an existing branch is as follows:
svn copy SOURCE_BRANCH_URL DESTINATION_URL -m "My descriptive log message."
In this command, SOURCE_BRANCH_URL is the URL of an existing branch, and
DESTINATION_URL is the URL at which the new branch will be created as a copy
of the source branch. The DESTINATION_URL should normally specify a location
inside the branches directory or inside the tags directory. This command
makes an immediate commit that creates the new branch on the server.
The SOURCE_BRANCH_URL and DESTINATION_URL can be absolute repository URLs,
for example:
C:\Users\Alex\my_work_dir> svn copy https://svn.example.com/MyRepo/trunk https://svn.example.com/MyRepo/branches/my_new_branch -m "Create branch my_new_branch."
Or these URLs can be relative repository URLs (relative to the repository’s root), for example:
C:\Users\Alex\my_work_dir> svn copy "^/trunk" "^/branches/my_new_branch" -m "Create branch my_new_branch."
To be able to use the shorthand relative URLs, you need to run the command inside a working copy checked out from that repository.
Windows Command Prompt requires that you enclose relative repository URLs in
quote marks, because the caret (^) is an escape character in Windows Command
Prompt. In PowerShell and on Unix-like command shells, quote marks are optional
around relative URLs that don’t contain spaces.
Since svn copy is a command for a tracked tree change, it creates a tracked
copy. That is, Subversion will be able to tell that the my_new_branch
originated as a copy of the trunk and records from which revision of the
trunk the branch my_new_branch split off.
For an example of creating a new branch as part of the standard feature branch workflow, see Step 1: Create a new branch in that workflow.
The command to display the working copy’s current branch
To find out which branch (which repository URL) the root of your working copy currently reflects, run the following command from the root of your working copy:
C:\Users\Alex\my_work_dir> svn info
This command displays the reflected URL and other information about the working
copy directory in which you run the command. In the output, look at the
Relative URL, which displays the branch that you are currently on. That is,
the Relative URL is the repository URL reflected by the working copy directory
in which you run the command.
For example, the following Relative URL means that the root of the working
copy (my_work_dir) reflects the branch called my_new_branch:
C:\Users\Alex\my_work_dir> svn info
…
URL: https://svn.example.com/MyRepo/branches/my_new_branch
Relative URL: ^/branches/my_new_branch
…
The command to switch to a different branch
The syntax of the command to switch an existing working copy to a different branch is as follows:
svn switch BRANCH_URL PATH
The BRANCH_URL is the URL of the branch in the repository that you want to
switch to. Typically, you can specify it as a relative repository URL (relative
to the repository’s root), e.g. "^/branches/my_new_branch". Alternatively, you
can specify it as an absolute URL.
PATH is the local working copy path that will be switched to the desired
branch. Importantly, you should normally switch your whole working copy to
reflect one particular branch. An explicit PATH is optional and might look
like C:\Users\Alex\my_work_dir. When PATH is not specified explicitly
(as in the example below), it means that the implied PATH is the current
directory in which you run the switch command. So, when using the implied
PATH (as in the example below), you need to run the switch command from the
root directory of your working copy, to switch the entire working copy to the
desired branch.
For example, to switch your working copy my_work_dir to reflect the branch
my_new_branch, you might run the following command from the root for the
working copy:
C:\Users\Alex\my_work_dir> svn switch "^/branches/my_new_branch"