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

451,074

Solution 1

Hmm, not sure I agree with Nick re tag being similar to a branch. A tag is just a marker

  • Trunk would be the main body of development, originating from the start of the project until the present.

  • Branch will be a copy of code derived from a certain point in the trunk that is used for applying major changes to the code while preserving the integrity of the code in the trunk. If the major changes work according to plan, they are usually merged back into the trunk.

  • Tag will be a point in time on the trunk or a branch that you wish to preserve. The two main reasons for preservation would be that either this is a major release of the software, whether alpha, beta, RC or RTM, or this is the most stable point of the software before major revisions on the trunk were applied.

In open source projects, major branches that are not accepted into the trunk by the project stakeholders can become the bases for forks -- e.g., totally separate projects that share a common origin with other source code.

The branch and tag subtrees are distinguished from the trunk in the following ways:

Subversion allows sysadmins to create hook scripts which are triggered for execution when certain events occur; for instance, committing a change to the repository. It is very common for a typical Subversion repository implementation to treat any path containing "/tag/" to be write-protected after creation; the net result is that tags, once created, are immutable (at least to "ordinary" users). This is done via the hook scripts, which enforce the immutability by preventing further changes if tag is a parent node of the changed object.

Subversion also has added features, since version 1.5, relating to "branch merge tracking" so that changes committed to a branch can be merged back into the trunk with support for incremental, "smart" merging.

Solution 2

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).

Solution 3

In addition to what Nick has said you can find out more at Streamed Lines: Branching Patterns for Parallel Software Development

enter image description here

In this figure main is the trunk, rel1-maint is a branch and 1.0 is a tag.

Solution 4

In general (tool agnostic view), a branch is the mechanism used for parallel development. An SCM can have from 0 to n branches. Subversion has 0.

  • Trunk is a main branch recommended by Subversion, but you are in no way forced to create it. You could call it 'main' or 'releases', or not have one at all!

  • Branch represents a development effort. It should never be named after a resource (like 'vonc_branch') but after:

    • a purpose 'myProject_dev' or 'myProject_Merge'
    • a release perimeter 'myProjetc1.0_dev'or myProject2.3_Merge' or 'myProject6..2_Patch1'...
  • Tag is a snapshot of files in order to easily get back to that state. The problem is that tag and branch is the same in Subversion. And I would definitely recommend the paranoid approach:

    you can use one of the access control scripts provided with Subversion to prevent anyone from doing anything but creating new copies in the tags area.

A tag is final. Its content should never change. NEVER. Ever. You forgot a line in the release note? Create a new tag. Obsolete or remove the old one.

Now, I read a lot about "merging back such and such in such and such branches, then finally in the trunk branch". That is called merge workflow and there is nothing mandatory here. It is not because you have a trunk branch that you have to merge back anything.

By convention, the trunk branch can represent the current state of your development, but that is for a simple sequential project, that is a project which has:

  • no 'in advance' development (for the preparing the next-next version implying such changes that they are not compatible with the current 'trunk' development)
  • no massive refactoring (for testing a new technical choice)
  • no long-term maintenance of a previous release

Because with one (or all) of those scenario, you get yourself four 'trunks', four 'current developments', and not all you do in those parallel development will necessarily have to be merged back in 'trunk'.

Solution 5

In SVN a tag and branch are really similar.

Tag = a defined slice in time, usually used for releases

Branch = also a defined slice in time that development can continue on, usually used for major version like 1.0, 1.5, 2.0, etc, then when you release you tag the branch. This allows you to continue to support a production release while moving forward with breaking changes in the trunk

Trunk = development work space, this is where all development should happen, and then changes merged back from branch releases.

Share:
451,074
James Aguilar
Author by

James Aguilar

independent game developer.

Updated on July 18, 2022

Comments

  • James Aguilar
    James Aguilar almost 2 years

    I've seen these words a lot around Subversion (and I guess general repository) discussions.
    I have been using SVN for my projects for the last few years, but I've never grasped the complete concept of these directories.

    What do they mean?

    • badmoon
      badmoon over 15 years
      Here's a good article I ran across explaining how/when to use trunk, branch, and tags. I'd not used source control before, but this article made it pretty easy for a noob like me to understand. Day-to-day with Subversion
  • Ken Liu
    Ken Liu over 14 years
    The confusion with tags and branches is that in svn there really is no distinction between them, besides the name of the directory. In svn you are able to commit changes to a tag, and in fact it is difficult to prevent this. Most other VCSes treat tags as immutable snapshots (points in time).
  • Baruch
    Baruch over 12 years
    It is not true that in SVN tags are lightweight. In SVN, tags are a full code export, and lose any reference to where in the source tree they cam from.
  • Jeff Noel
    Jeff Noel over 11 years
    Tags directory is also often used for milestones testing and verification by the regular user. This would be a good place to put a prototype too (just some ideas on top of my head).
  • Darryl
    Darryl almost 11 years
    An alternative perspective is that the opposite is true, that imposing the concept of tags on subversion's object model would be leaky abstraction in the opposite direction. As I'm guessing you know, subversion was a reaction to CVS, an attempt to "do CVS right." I couldn't find the reference, but the original subversion designers have said they threw out the concept of tags 100% deliberately, that the distinction between branches and tags is purely a policy issue. If teams want to impose policy and convention on top of subversion's object model, so be it. That's exactly what we have today.
  • Josh Kelley
    Josh Kelley almost 10 years
    @baruch - That's completely wrong. Tags are lightweight and are (as far as Subversion itself is concerned) identical to branches.
  • Jeromy French
    Jeromy French over 9 years
    Love the use-case detail. Thanks @gregmac.
  • David W.
    David W. about 9 years
    @KenLiu There are hooks that can make tags immutable. That is, you can create, and checkout a tag, but not make any changes. Of course, a tag being just part of the repository means the full history is available. If someone changes a tag, you can track that and why. In many VCS, if you modify a tag, there may not be any way to know.
  • Wolf
    Wolf about 9 years
    Maybe stable branches should be mentioned: changes made there are normally not merged back into the trunk.
  • Cardin
    Cardin about 9 years
    Can I get a quote on where it's stated that tags/branches are lightweight? It doesn't seem that way..
  • gbjbaanb
    gbjbaanb almost 9 years
    @Wolf he could be - that diagram is pretty generic regardless of the tooling. All SCMs use different words but the same concepts, there's no difference between trunk and Main; or trunk and master. That diagram shows how my current company uses SVN.
  • Wolf
    Wolf almost 9 years
    @gbjbaanb Thanks for sharing. ...and tags seem not to be addressed by the question. Is it pure coincidence (also in your current company) that that no merges go from main to from maintained branches?
  • gbjbaanb
    gbjbaanb almost 9 years
    @Wolf No coincidence - only branch from trunk, do work, merge back onto trunk. Then branch off trunk to a tag branch. We're considering another 'trunk' called Integration that has finished branches merged to it for testing that doesn't constitute a release, trunk is still used for those branches that we decide to put in the next release. The only time you merge from trunk to a branch is to update a long-running branch, but its better (and easier) to simply create a new branch off trunk and merge your old branch's changes to it if you need that.
  • James Wierzba
    James Wierzba almost 9 years
    What would be the difference between a stable branch and a tag then?
  • MikeT
    MikeT almost 9 years
    My understanding is that in a "perfect world" no development should ever happen in the trunk, the trunk should always be either the exact code that is in live or code that is about to be released into live. as such that would make the branches the main body of development.
  • MikeT
    MikeT almost 9 years
    Also my understanding of what a tag is supposed to to is that a tag is more like a secondary trunks, ie you have a product on the market that has an active user base. you decide to release version 2 as a seperate product rather than a upgrade, however if a bug is located in version 1 of your product you need to provide support to your existing user base even if they haven't upgraded to version 2, so you would create a tag before moving to v2 and then any bug fixes required on v1 could be performed on branches originating from the v1 tag
  • Nam G VU
    Nam G VU over 8 years
    This should be the accepted answer which is so much better ^^
  • John
    John over 8 years
    @Cardin I don't have reference right now, but important to note tags are lightweight on the server, but not client. If you checkout all tags, you'll get that many full copies. However, if you look at repository size on server, it will only increase by a few bytes per tag. This is why you should not checkout the root directory, generally speaking.
  • Vering
    Vering about 8 years
    I believe a tag should be made everytime the code in trunk (or a branch) is released. By "released" I mean a version x.y.z that can be deployed in test or production. If a bug shows in version x.y.z, but trunk has changed due to new development, tag x.y.z can be copied to branch x.y.z and the bug fixed here. I think the same could be achieved by noticing the SVN-revision number when releasing, and the checking out this revision when fixing the bug in production. But a tag is more explicit.
  • StackzOfZtuff
    StackzOfZtuff almost 6 years
    This does not answer the original question. The answer instead gives a (correct) general introduction to the concepts of "Trunk", "Branch" and "Tag" in common usage. HOWEVER: This is NOT how SVN does these things. Namely: The "Tag" concept as an immutable timestamped snapshot has NO support in SVN. And unless you add immutability yourself via a pre-commit hook then a "TAG" in SVN is just a "BRANCH" that you chose to put in a directory that you chose to name "Tag". And all that's stopping you from modifying it afterwards is an unenforced convention.
  • StackzOfZtuff
    StackzOfZtuff almost 6 years
    Some thing goes for "Trunk": The explanation of the general concept is correct. However in SVN "Trunk" gets NO special treatment. It's just another folder name for branches. Enforced by nothing more than convention. For further details see Eric's answer.
  • Chris Voon
    Chris Voon over 5 years
    Wikipedia defines trunk as the unnamed branch (version) of a file tree under revision control. Trunk is a concept used primarily in SVN. The default branch in Git is called a master branch. There isn't any unnamed branch in Git, hence no trunk.
  • Jason S
    Jason S over 5 years
    This is your particular workflow, it is not applicable in general.
  • apple apple
    apple apple over 4 years
    @ChrisVoon as @ StackzOftuff said, trunk is not unnamed branch in SVN, it's a branch* named trunk. (*for detail, I'd recommend look at @ EricZBeard's answer.)
  • Darryl
    Darryl about 4 years
    @ChrisVoon The Wikipedia definition is too restrictive. It is based on older version control systems like CVS that really do have a default no-name place to commit changes. That no-name place is referred to as "the trunk" in conversation. It was an appropriate name because a repository started out with nothing but the trunk, and everything else branches out from there. It was impossible to create a branch that doesn't somehow trace back to the trunk. Both git and svn have conventions that serve the same purpose as trunk. Although they are just conventions, trunk is still an appropriate term.
  • Darryl
    Darryl about 4 years
    @Cardin Since you asked for a reference, take a look at the "Cheap Copies" block on this page: svnbook.red-bean.com/en/1.7/….