In this article, I have assumed that the reader is aware of the basic functionality of Subversion. This article has been written to make the usage of Subversion more efficient and more effective, as not much information is available on this subject in context of Subversion.
Although most of the things are already mentioned in the Subversion Documentation, but going through such vast information in one go becomes something uncommon. So it is good to have small articles targetting a specific feature which can expose the functionality and will get the attention. Without even any extra effort it gets feeded in mind, making understanding of the subject better.
I installed Subversion and started using it, but I started getting problems in maintenance when the code base spreaded and required maintenance of multiple versions.
To find the solution I studied the documentation available, to use Subversion(SVN) more effectively. One of the important things I read was about "What should be the ideal Repository Structure":
So lets understand the options available:
In this article I have followed Major.Minor.Build.Revision versioning practice which is very standard, details of it are as under:
In this version number is physically represented as a four-part string with the following format:
For example, version 1.5.60204.0 indicates 1 as the major version, 5 as the minor version, 60204 as the build number, and 0 as the revision number.
- Major: Major releases introduce major new technologies and changes that render previous production releases obsolete.
- Minor: Minor releases depict feature level enhancements. Addition of features between releases result in incremented minor release.
- Build: This is auto-generated number, assigned for each build on a day basis. It has YMMDD format, So Feb 04th 2006 shall be 60204.
Note: Build number for revisions (read bug-fixes to production releases) shall remain same as originally released in production.
- Revision: This is reset to zero, for each new major/minor version released. For all later bug-fixes, patches to releases that reach production, this number shall sequentially increment.
Trunk is the main branch of development.
Isolating changes onto a separate line of development is called Branching. Branches are used to try out new feature without disturbing the main line of development. And as the new feature becomes stable the development branch is merged back into the main branch (trunk).
Tagging is to mark particular revisions (e.g. release version), so that you can recreate a certain build or environment at any time. Tags are used to create a static snapshot of the project at a particular stage. Tagging of the project is mostly done along with the successful build and generally it is done by the automated build process.
Important Note: Subversion itself makes no distinction between tags and branches, but they are there for different purpose. Tags are not normally used for development, Branches must be used for that purpose. So working on a tag revision is not a good idea. So you must remember this as there is nothing to stop you doing this by mistake. However there are few SVN-Client Applications (like TortoiseSVN) which will warn you if you try to commit to a path in the repository which contains /tags/. But I am not sure about other SVN-Clients.
Figure 1: Example of a Subversion Repository Structure (expanded).
Branching or Tagging done by Subversion are just internal links (cheap copies) pointing to a specific tree/revision and thus can be created very quickly and also take up almost no extra space in the repository. If you modify a working copy created from a branch and commit , then all changes go to the new branch and not to the trunk. Only the modifications are stored and the rest remains a cheap copy.
Many times it may happen that you need to make further changes to a release which has been already tagged. The correct way to handle this is to create a new branch from the tag first and commit the branch. Make Changes on this branch and tag the branch for every build with increment in the Revision number.
So finally "What should be the ideal Repository Structure"
Following folder/directories must be created, all at the repository root level:
How to make the Repository Structure:
- Do SVN Checkout to a new folder.
- Create the folder /trunk inside the root repository folder.
- Create the folder /branches inside the root repository folder.
- Create the folder /tags inside the root repository folder.
- Copy the project files (which are to be Source Controlled) in the /trunk folder.
- Add the files and folder to SVN and do SVN Commit.
- Create a Branch with Major and Minor mentioned in the branch name for e.g. "v1_0_X" **
- Now you can delete the new folder from your machine (not from SVN) as it is now saved in SVN.
- Checkout the newly created branch. Now you can start working on this.
If you need to make further changes to a release which has been already tagged, following steps must be followed:
- Checkout the tagged revision to a new folder.
- Create a new Branch from the checkedout project.
- Switch the working copy to new Branch (or in simple words Delete the just created new folder and checkout the new branch to a new folder.)
For e.g. Suppose you need to make further changes to a release tagged "v1_0_60924_0". Steps will be as under:
- Checkout the tag "v1_0_60924_0" to a new folder say "C:\HelloWorld_temp".
- Create a new branch "v1_0_60924_X" *** by giving the command from within the above folder.
- Switch the working copy:
- Deleting the "C:\HelloWorld_temp" folder.
- Checkout the branch "v1_0_60924_0" to a folder "C:\Projects\HelloWorld".
** Branch name v1_0_X dissected: "v" represents the word "Version", "1" is Major, "0" is Minor and "X" is to indicate that along with the changes (or during the Build process) Tags will be created with dynamic Build and Revision numbers, for e.g. "v1_0_60923_0" here 60923 is the Build Number which represents the date of build (6 is the year 2006, 09 is the Month and 23 is the Date), after Build Number there comes the Revision Number which will get incremented with every next build during the day.
*** In case of already tagged release Branch name used is "v1_0_60924_X" because for further builds on this Branch only revision number will get incremented. Mostly this happens when a Build is released or finalized to be released, then for bug-fixes and patches to be release the Build number is freezed and only Revision number changes.