SVN trunk, branches and tags

In this post, I provide details about how I personnaly handle SVN trunk, branches and tags. This approach is also known as “branch always”, with minor differences. This might not be the best approach, but it will give beginners some explanations on what trunk, branches and tags are, and how to handle them.

Of course, feel free to leave comments on this post if some clarifications are needed, if some mistakes were made, or if you disagree with my statements.

An easy comparison

Working with SVN is somewhat like growing a tree:

  • a tree has a trunk and some branches
  • branches grow from the trunk, and thinner branches grow from thicker branches
  • a tree can grow with a trunk and no branch (but not for long)
  • a tree with branches but no trunk looks more like a bundle of twigs fallen on the floor
  • if the trunk is sick, so are the branches and eventually, the whole tree can die
  • if a branch is sick, you can cut it, and another one may grow
  • if a branch grows too much, it may become too heavy for the trunk, and the tree will fall down
  • when you feel your tree, your trunk, or a branch is nice looking, you can take a picture of it to remember how nice it was that day

Trunk

With the “branch always” approach, the trunk is the main place were stable code can be found. This is like the assembly line of a car factory, putting finished car parts together.

Here is how you should deal with a SVN trunk:

  • do NEVER work directly on the trunk, unless you have to deal with a bug which is quick and easy to fix (a few characters), or if you have to ADD a few files which hold no logic (like media files: images, videos, css, etc)
  • do not make too many exceptions to the previous statement, those are really special cases, every other situation must imply the creation of a branch (see below)
  • do not commit changes (from a branch merge) to the trunk which may break it
  • if at some point you happen to break the trunk, bring some cake the next day (“with great power comes… huge cake”)

Branches

A branch is a “cheap copy” of a subtree (ie, the trunk or a branch) of a SVN repository. It works a little bit like symbolic links on UNIX systems, except that once you make modifications to files within a SVN branch, these files evolve independently from the original files which were “copied”. When a branch is completed and considered stable, it must be merged back to its original copy, that is: back to the trunk if it was copied from the trunk, or back to its parent branch if it was copied from a branch.

Here is how you should deal with SVN branches:

  • if you need to alter your application or develop a new feature for it, create a new branch from the trunk, and make your development on that branch
  • new branches must be created from the trunk, except for new sub-branches (if needed) which must be created from a branch
  • when you create a new branch, you should switch to it immediately; if you don’t, why did you create the branch in the first place?

Tags

Internally, SVN branches and SVN tags are the same thing, but conceptually, they differ a lot.
Remember the “take a picture of the tree” thing written earlier? Well, this is exactly what a SVN tag is: a snapshot with a name of a specific revision of the trunk, or of a branch.

Here is how you should deal with SVN tags:

  • as a developer, do never switch to/checkout from/commit to a SVN tag: a tag is some sort of “picture”, not the real thing; tags are to be read, never written
  • on specific/critical environments (production, staging, testing, etc), checkout and update from a fixed tag, but do never commit to a tag
  • for the aforementioned environments, create tags with names like “production”, “staging”, “testing”, etc. You can also tag by sofware version and/or by project maturity: “1.0.3”, “stable”, “latest”, etc.
  • when the trunk is stable and ready to be released publicly, re-create tags accordingly, then update the concerned environments (production, staging, etc)
  • do not tag a tag

Example workflow

Say you have to add a feature to a project under version control. Here are the steps you should achieve to do so:

  • get a new working copy of the project (through a SVN checkout or a SVN switch) from the trunk
  • create a new SVN branch and give it a name which allows to understand what it is all about (say, “feature-faq-development”)
  • SVN switch to the new branch (“/branches/feature-faq-development”)
  • make the needed development to complete the new feature (and of course, make a lot of tests, even before you start coding), commit sub-parts of your development when needed
  • once the feature is complete and stable (and committed), merge the trunk into the branch and resolve conflicts if there are some, then commit your changes
  • with the approval of your peers, switch to the trunk
  • merge your branch within your working copy (trunk), and resolve conflicts if there are some
  • re-check your development with the merged code
  • if possible, ask one of your peer to do a code review of your changes with you
  • commit your merged working copy to the trunk
  • if some deployment must be achieved on specific environments (production, etc), update the related tag to the revision you just committed in the trunk
  • deploy on the concerned environments with a SVN update
  • rename the branch so that it’s made clear it won’t be used anymore (“/branches/obsolete-feature-faq-development”)
  • eventually, delete the branch after a while

Extra resources:

47 comments

  1. I am not sure, whether I agree with the “never work on the trunk” philosophy. I am used to projects, where the trunk is always used for the development work on the current release. That way one does not need to constantly merge the development branches into the trunk. Plus, what is the trunk good for, if you don’t work on it?

    1. That is another approach: working directly on the trunk allows to save time from branch/merge operations, which can be a pain for small sized teams, at the cost of a more fragile trunk. Also, some companies deal this way with SVN, with the principle of “you can break the trunk, but not for long” (from a few hours to a few days). Use the SVN strategy that best suits your needs at a given time, and change it when it’s not helping you anymore; there is no single SVN strategy which would fit every situation.

      1. On our company, we are abiding these steps. First we create a new branch from trunk, then on staging, we create tag from branch ie. 1.0.3-qa1 , sometimes there are back logs to deal with, so we back on the branch and then recreate tag after bug fixing, which is 1.0.3 -qa2., when the tickets are closed, we recreate the final tag as 1.0.3, On our release notes we export tags/1.0.3 on production server and merge the final tag into trunk.This is a good practice specially on a large project like e-commerce.

  2. Really interesting!

    However, I think that for team-oriented work you have to slightly modify the process (from the fifth step above):

    # once the feature is complete and stable (and committed), with the approval of your peers, merge the trunk into the branch(!) and resolve conflicts if there are some,
    # then switch to the trunk, and
    # merge your branch within your working copy (trunk), and resolve conflicts if there are some

    But for non-coop work, your method is perfect I think!

    1. Hi Mikael, thanks for your feedback, this is exactly the kind of feedback I was expecting. This extra step will indeed solve “conflict surprises” often encountered when merging back to trunk with larger teams. I will update the post to reflect your remark.

  3. I think a big feature of always working in a branch is that I can check-in freely, knowing that I will never disturb other developers or break the trunk build. I can treat each check-in as a “draft”… especially useful when making larger, more complex source changes.

    SVN (as of 1.5, I think) tracks merges with properties on directories, so it makes the merge process a whole lot easier… I actually keep using my branch after a trunk merge… This way, I create a branch to do several fixes, and can merge after each fix (or set of fixes), keeping up with the trunk changes as I do.

  4. IMHO with this methodology you can loose the benefits of continuous integration and the fast feedback from the build/test runs, because a little bit hard to configure the CI server to manage all development branches.

  5. You had said this about trunk…

    “do NEVER work directly on the trunk, unless you have to deal with a bug which is quick and easy to fix (a few characters), or if you have to ADD a few files which hold no logic (like media files: images, videos, css, etc)”

    But what if you are doing Continuous integration? We would want to keep committing to trunk and merging every commit so that trunk is release ready at any point of time.

  6. Thanx for this article! It is very well written, so now I finaly understand what’s the point of branches.
    I’ll be using them more often from now on.

    I have a reply to comments about resolving conflicts. I believe there’s no difference in number of conflicts, whether you commit to the trunk or merge the branch. If conflicts exist in a branch, thay would also exist when committing to trunk.
    The only difference is that when merging branch to trunk (or other direction), you have to resolve all conflicts together. But sometimes that is better – I don’t want to worry about them every time I commit, but I’m prepared to work on them at the end of subproject.

  7. I am just starting with SVN and this is just what I need at this stage. I am a little unclear as to what your criteria for establishing a new trunk might be.

  8. Thanks for this post. It really covers what happens in every day development life. It is good ii is so short and human understandable. Nice work.

  9. Pingback: Anonymous
  10. It was such a nice article for beginners.
    i was trying to understand why do we leave trunk a non development stream.
    if we have serial releases it is better to do the development on trunk and create tags for every milestone which reduces the burden of branching and merging back.
    Ofcourse this works only when there are serial releases of application

  11. Hi,
    This article is really nice but I have another question : tags is done for stable version. Ok How to set svn in order to be abble to create a tag once and to prohibiting tag modifications or destruction. Like that if a member of the team is not aware of svn rules is do not do a mistake by detroying or modifying a tagged version ?

  12. Thanks man, really helped a lot in understanding the concetps from the basics. ‘The Tree’ example, nice and innovative way to make one understand the SVN basics.

  13. Great Article!!

    Explains almost everything you need to know about SVN trunk, branches and tags, so perfectly.

    Thank you.

  14. Such an excellent article, thank you.

    The one thing I wish was that your article included the actual SVN commands to use for each of your recommend steps. Maybe a future blog post?

  15. Exactly the kind of article I was looking for to clear the clouds about the correct process of branching and advantages of the “always branching” approach. Thanks.

  16. What honestly influenced you to create “SVN trunk, branches and tags | Jean-Michel Feurprier”?
    I personallyabsolutely enjoyed the blog post!

    Thanks for the post ,Corazon

  17. Very interesting article; well articulated and easily digestible. I have a comment that, if few diagrams and SVN commands were part of this article, this would have been a sweeter cake.

  18. nice article to understand difference between trunk, branch and tag in svn. I love the way you explained them via picture, must read for any programmer.

  19. Hey I appreciate your effort, its very nice :) But I have a doubt here, you talked about trunk and branch right, what about twig? I am given a task to create branch from a branch i.e., a twig and make changes in them. can you please throw some light on it??

    Thanks,
    Apoorva R

Leave a Reply

Your email address will not be published. Required fields are marked *