[svn] What do "branch", "tag" and "trunk" mean in Subversion repositories?

First of all, as @AndrewFinnell and @KenLiu point out, in SVN the directory names themselves mean nothing -- "trunk, branches and tags" are simply a common convention that is used by most repositories. Not all projects use all of the directories (it's reasonably common not to use "tags" at all), and in fact, nothing is stopping you from calling them anything you'd like, though breaking convention is often confusing.

I'll describe probably the most common usage scenario of branches and tags, and give an example scenario of how they are used.

  • Trunk: The main development area. This is where your next major release of the code lives, and generally has all the newest features.

  • Branches: Every time you release a major version, it gets a branch created. This allows you to do bug fixes and make a new release without having to release the newest - possibly unfinished or untested - features.

  • Tags: Every time you release a version (final release, release candidates (RC), and betas) you make a tag for it. This gives you a point-in-time copy of the code as it was at that state, allowing you to go back and reproduce any bugs if necessary in a past version, or re-release a past version exactly as it was. Branches and tags in SVN are lightweight - on the server, it does not make a full copy of the files, just a marker saying "these files were copied at this revision" that only takes up a few bytes. With this in mind, you should never be concerned about creating a tag for any released code. As I said earlier, tags are often omitted and instead, a changelog or other document clarifies the revision number when a release is made.


For example, let's say you start a new project. You start working in "trunk", on what will eventually be released as version 1.0.

  • trunk/ - development version, soon to be 1.0
  • branches/ - empty

Once 1.0.0 is finished, you branch trunk into a new "1.0" branch, and create a "1.0.0" tag. Now work on what will eventually be 1.1 continues in trunk.

  • trunk/ - development version, soon to be 1.1
  • branches/1.0 - 1.0.0 release version
  • tags/1.0.0 - 1.0.0 release version

You come across some bugs in the code, and fix them in trunk, and then merge the fixes over to the 1.0 branch. You can also do the opposite, and fix the bugs in the 1.0 branch and then merge them back to trunk, but commonly projects stick with merging one-way only to lessen the chance of missing something. Sometimes a bug can only be fixed in 1.0 because it is obsolete in 1.1. It doesn't really matter: you only want to make sure that you don't release 1.1 with the same bugs that have been fixed in 1.0.

  • trunk/ - development version, soon to be 1.1
  • branches/1.0 - upcoming 1.0.1 release
  • tags/1.0.0 - 1.0.0 release version

Once you find enough bugs (or maybe one critical bug), you decide to do a 1.0.1 release. So you make a tag "1.0.1" from the 1.0 branch, and release the code. At this point, trunk will contain what will be 1.1, and the "1.0" branch contains 1.0.1 code. The next time you release an update to 1.0, it would be 1.0.2.

  • trunk/ - development version, soon to be 1.1
  • branches/1.0 - upcoming 1.0.2 release
  • tags/1.0.0 - 1.0.0 release version
  • tags/1.0.1 - 1.0.1 release version

Eventually you are almost ready to release 1.1, but you want to do a beta first. In this case, you likely do a "1.1" branch, and a "1.1beta1" tag. Now, work on what will be 1.2 (or 2.0 maybe) continues in trunk, but work on 1.1 continues in the "1.1" branch.

  • trunk/ - development version, soon to be 1.2
  • branches/1.0 - upcoming 1.0.2 release
  • branches/1.1 - upcoming 1.1.0 release
  • tags/1.0.0 - 1.0.0 release version
  • tags/1.0.1 - 1.0.1 release version
  • tags/1.1beta1 - 1.1 beta 1 release version

Once you release 1.1 final, you do a "1.1" tag from the "1.1" branch.

You can also continue to maintain 1.0 if you'd like, porting bug fixes between all three branches (1.0, 1.1, and trunk). The important takeaway is that for every main version of the software you are maintaining, you have a branch that contains the latest version of code for that version.


Another use of branches is for features. This is where you branch trunk (or one of your release branches) and work on a new feature in isolation. Once the feature is completed, you merge it back in and remove the branch.

  • trunk/ - development version, soon to be 1.2
  • branches/1.1 - upcoming 1.1.0 release
  • branches/ui-rewrite - experimental feature branch

The idea of this is when you're working on something disruptive (that would hold up or interfere with other people from doing their work), something experimental (that may not even make it in), or possibly just something that takes a long time (and you're afraid if it holding up a 1.2 release when you're ready to branch 1.2 from trunk), you can do it in isolation in branch. Generally you keep it up to date with trunk by merging changes into it all the time, which makes it easier to re-integrate (merge back to trunk) when you're finished.


Also note, the versioning scheme I used here is just one of many. Some teams would do bug fix/maintenance releases as 1.1, 1.2, etc., and major changes as 1.x, 2.x, etc. The usage here is the same, but you may name the branch "1" or "1.x" instead of "1.0" or "1.0.x". (Aside, semantic versioning is a good guide on how to do version numbers).

Examples related to svn

Error "can't use subversion command line client : svn" when opening android project checked out from svn How to view changes made to files on a certain revision in Subversion Intellij idea subversion checkout error: `Cannot run program "svn"` How change default SVN username and password to commit changes? How to rename a file using svn? Connect Android Studio with SVN svn: E155004: ..(path of resource).. is already locked SVN Commit failed, access forbidden How to add an existing folder with files to SVN? Update OpenSSL on OS X with Homebrew

Examples related to branch

Get git branch name in Jenkins Pipeline/Jenkinsfile Why do I have to "git push --set-upstream origin <branch>"? Your configuration specifies to merge with the <branch name> from the remote, but no such ref was fetched.? When does Git refresh the list of remote branches? Fix GitLab error: "you are not allowed to push code to protected branches on this project"? Git push: "fatal 'origin' does not appear to be a git repository - fatal Could not read from remote repository." Git: Merge a Remote branch locally git pull from master into the development branch Depend on a branch or tag using a git URL in a package.json? How can I copy the content of a branch to a new local branch?

Examples related to terminology

The differences between initialize, define, declare a variable What is the difference between a web API and a web service? What does "opt" mean (as in the "opt" directory)? Is it an abbreviation? What's the name for hyphen-separated case? What is Bit Masking? What is ADT? (Abstract Data Type) What exactly are iterator, iterable, and iteration? What is a web service endpoint? What is the difference between Cloud, Grid and Cluster? How to explain callbacks in plain english? How are they different from calling one function from another function?

Examples related to trunk

Svn switch from trunk to branch What is trunk, branch and tag in Subversion? What do "branch", "tag" and "trunk" mean in Subversion repositories?