Skip to main content

Subversion for starters : Trunk, branch, tag how and when to use?

Lets ponder on some details about Subversion to begin with

Subversion is a free/open source version control system (VCS). That is, Subversion manages files and directories, and the changes made to them, over time. This allows you to recover older versions of your data or examine the history of how your data changed

Subversion is different as compared to typical file server as it remembers every change ever written to it—every change to every file, and even changes to the directory tree itself, such as the addition, deletion, and rearrangement of files and directories.

Do you need it?
If you need to archive old versions of files and directories, possibly resurrect them, or examine logs of how they've changed over time, then Subversion is exactly the right tool for you. If you need to collaborate with people on documents (usually over a network) and keep track of who made which changes, then Subversion is also appropriate. This is why Subversion is so often used in software development environments

How it works?
At its core is a repository, which is a central store of data(there can be multiple repositories sitting on the server for that matter). The repository stores information in the form of a filesystem tree—a typical hierarchy of files and directories. Any number of clients connect to the repository, and then read or write to these files. By writing data, a client makes the information available to others; by reading data, the client receives information from others.
So the user specific read/write permissions are always repository specific.

Now the main confusion, what is the difference between trunk, branch and tag?

The main development area. This is where your next major release of the code lives, and generally has all the newest features. This would also mean that trunk would be the main body of development, originating from the start of the project until the present.

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

In general, you would see two branch types:
  1. Feature Branch: If a particular feature is disruptive enough that you don't want the entire development team to be affected in its early stages, you can create a branch on which to do this work. 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.
  2. Fixes Branch: While development continues on the main trunk, a fixes branch can be created to hold the fixes to the latest released version of the software.

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


A very good example which I got from internet that throws more light on explaining the usages of the above three terms is following -

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(features decided for 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 very important thing for learners to understand is the value of proper commits(check-ins) and commit messages

Commit as often as is useful; rule of thumb is commit whenever you have done sufficient work that it would be a problem having to re-do it if the modifications got lost; sometimes I commit every 15 minutes or so, other times it might be days (yes, sometimes it takes me a day to write 1 line of code)
I wouldn't worry about making "too many" commits/check-ins. It really sucks when you have to rewrite something, and it's nice to be able to rollback in small increments just in case.
So, I would say commit when you complete a functional piece of code, however small.
 "if the code isn't checked into source control, it doesn't exist."
Said that, don't use your repository as a backup solution. Don't commit code that doesn't actually work.

Commit messages are very useful and required when you are actually trying to find out how the file/dir/repo has evolved to the current version. And also gives other developers, who might also be working on/using the same file, an idea and perspective about the update in a specific file.

Some good commit message can be following
Changed paragraph separation from indentation to vertical space.
Fix: Extra image removed.
Fix: CSS patched to give better results when embedded in javadoc.
Add: A javadoc {@link} tag in the lyx, just to show it's possible.
- Moved third party projects to ext folder.
- Added lib folder for binary library files.
Fix: Fixed bug #1938.
Add: Implemented change request #39381.

Well, subversion is a huge topic to cover a single blog, and I have limited my blog to mainly the basic subversion; trunk, branches, tags and commits to keep is relatively short and to the point.
I hope and expect that this text might come in handy for all the beginners who are trying their hands on VCSs.

Sandeep Rajoria

P.S. - And don't forget to check my Analytics app here


Pankaj Agrawal said…
Such a Nice Content under the title. Got many New things to learn

Thanks sir

Popular posts from this blog

Multi Tenancy with Codeigniter

In this post I will show you how I converted my normal Codeigniter application into a multi-tenant system.(first step to a SaaS implementation) Note - This implementation is a separate DB multi-tenancy implementation. Lets say we have an up and running CI application name ci_app , with the directory structure like this ./application ./application/config ./application/ many other important directories ./asset ./asset/js ./asset/images ./asset/css ./system ./index.php which is accessed through browser like http://localhost/ci_app So to implement the multi-tenant arch we are most concerned about the following files, and we will be editing them ./index.php ./application/config/config.php ./application/config/database.php And also we need to create a few new ones Create a tenant folder in your www root directory, lets say tenant_1 Cut the ./index.php from ci_app and paste it in tenant_1 directory  Create a blank file config.php in tenant_1 directory Crea

Profiling and checking PHP error_reporting in a Codeigniter App, without editing the config!!

Hi all, You must have definitely used the Profiling in Codeigniter and error_reporting many a times in Development and Testing environment, but I am sure you must have missed it on a real Production environment. As there are scenarios, where you want to quickly debug the Production application and find out what PHP errors is the application throwing, check the page profile, that too without putting the time and effort in replicating the whole production environment on your local machine, or perhaps a testing server. This small piece of code(we could perhaps call it a hack), which I have used in almost all of my CI applications, will make your life very easy, without losing anything on the security of the system. Following points, essentially sum up what exactly it does - Check for the dev(or root or admin, whichever name you use for the su access), if it is logged in, as we don't want others to see all the Profile data and other errors. Check for a specific query str

D3.js, the most powerful visualization library I came across

Hello Friends!! This post is dedicated to D3.js , which I came across a few months back. Prior to that, I always preferred Google Charts which catered to most of my charting needs. However, since I switched to D3.js I could not find a good reason to move back to Google Chart. If we take a very crude analogy, D3.js would be analogous to an Ubuntu of the OS world, while Google Charts could easily be a Windows 7(just that both of them are free in this case); in the sense that the control and the power the user(in our case the developer) gets from D3.js while working with it, is unmatchable . While Google Charts is simply too cool and simple for a free charting tool, but D3.js is a library which lets you create any chart that you could think and conceptualize, with so much of ease, and it lets you link any kind of interaction/control that you would want to put on events, on any of the elements of the chart. D3.js, like RaphaelJS and PaperJS is a library which is developed to