Software Development

Version control branching strategies

Almost two years ago we started a new project (related to SOA/BPM infrastructure) on a large telco organization. Project is going very well and run on production since last summer. We develop more and more modules and things going well. Now it’s time to transfer the knowledge to client’s developers. The main things that we have to taught them are naming conventions, source code, architecture and administration tasks. As we will be in the same team for a few more months, first of all we have to explain them our version control branching strategy.

So, on this post I will explain our approach on version control branching strategies. An approach that we defined after spending a lot hours on conversations and reading books.

Facts:

  • We have many individual/autonomous applications that are related to each other.
  • Each application is dependant to at least another application (based on WSDLs).
  • We do not have quality assurance manager, neither release manager, so we do all the work, which is related to design, development, release management and administration tasks.
  • We have defined 3 types of testing (related to release):
    • Unit testing: Testing that can be done by us (developers) without communicate with external systems (like CRM, Billing, etc.).
    • Integration testing: Testing that includes communication with external systems (Billing, CRM, etc.) and is done by developer(s).
    • User Acceptance Test: End-to-End testing that is performed by client without us.

Rules:

  1. We follow the unstable branching strategy. This means that trunk contains the latest code, regardless of how must stable it is.
  2. Branching is used only for release candidates, releases, bugfixes and experimental code.
  3. Use consistent tag-naming schemes for the tags:
    1. Branch tags will always start with ‘BT_’
    2. Release candidate prefix is ‘RC_’
    3. Release prefix is ‘R_’
    4. Bugfix prefix is ‘BF_’
    5. Experimental code prefix is ‘EC_’
    6. Developer tags start with ‘DEV_’
    7. Branch names will always start with ‘BR_’
  4. A tag is always created on trunk:
    1. Before create a branch: <branchName>_BASE (e.g RC_2_0_ApplicationName_BASE)
    2. Before merge a branch to trunk: <branchTabName>_PMB (PMB: Pre Merge Branch)
    3. After merge branch to trunk: <branchTagName>_AMB (AMB: After Merge Branch) (e.g. RC_2_0_ApplicationName_AMB)
  5. Always do tags in branches after do work, with suffix ‘–counter’ and always increase counter (e.g. BT_RC_2_0–1_ApplicationName).
  6. Merge back frequently; the fewer changes there are to the trunk, the easier they are to merge.
  7. Create a Wiki page for each application and write details for each individual tag and branch.
  8. Record tags in related issues/bugs on your bug tracking system.

The above rules/steps are for only one application, but they are the same for all applications.

OK, it’s time for the simple release management example. As at most times, an image is better than thousands of words. This is not always true, try to find an image to explain wise. I am sure you cannot. So many books have written, but still we cannot understand/define wise. So sad for human kind…. Let’s go to something more simple like release management. So, check the following image:

Release Candidate scenario of application PName:

  1. Development is done on TRUNC and all developers work there. Application is at stable release 1_9. and after a lot changes want to go to release 2_0. The underscore is used instead of dot to comply with most version control software variants (CVS is not accept the dot in tags)
  2. When developer finish his unit testing and as many integration tests he could accomplish, then decide that application is ready for integration and acceptance tests and so he creates a Tag on trunk with name ‘RC_2_0_PName_BASE’. This the release candidate timestamp on TRUNK, as tags are timestamps.
  3. Release Candidate 2_0 is branched using name ‘BR_RC2_0_PName’.
  4. During Integration Test an issue is raised. It is fixed on branch and then tagged as BT_RC2_0–1_PName.
  5. Developer decide that is better to merge the changes back to TRUNC, while the rest of the development team continues to work towards to RC3_0. So, two things must be done:
    1. Commits paused for AppName application (using a loud announcement like “Go for coffee I must merge to trunk”).
    2. He tags TRUNK with RC2_0–1_PName_PMB.
  6. Developer merges the branch to TRUNC.
  7. Developer do the required commits (if any) to have a valid application on TRUNC and create a new tag on TRUNC named RC2_0–1_PName_AMB. Developer announces “Go back to work” and unpauses commits on PName application.
  8. During Acceptance Test another issue is raised. Code needs a few modifications, after a few commits, issue is resolved and committed on branch. Then branch is tagged as BT_RC2_0–2_PName. No merge to trunk here (developer decides here as he is the release manager in our case)
  9. During Acceptance Test another issue is raised. Code needs a few modifications, after a few commits, issue is resolved and committed on branch. Then branch is tagged as BT_RC2_0–3_PName.
  10. Acceptance Tests are completed with the modified code unattached. Now release “2_0? is ready. Developer create a tag BT_R2_0_PName on branch, which is exactly the same code as BT_RC2_0–3_PName.
  11. Now, developer must merge the code to TRUNK. First pause the commits on the trunk and then creates a tag named R2_0_PName_PMB.
  12. Developer merge the changes to trunk.
  13. Then do additional required commits and create another tag named R2_0_PName_AMB and afterwards unpause the commits on TRUNK.
  14. While application (release 2_0) is running on production another issue is raised that needs a quick fix. Problem is fixed on branch and a tag is created on branch with name BT_RC2_0_1_PName.
  15. Additionally the quick fix is also tagged as release with tag name BT_R2_0_1_PName.
  16. Developer must (in most cases) merge the changes back to TRUNC while the rest of the development continues to work towards RC3_0. So, he pause the commits on application and tags TRUNK with R2_0_1_PName_PMB.
  17. Developer merge the changes from branch to trunk.
  18. Developer do the required commits to have a valid application on TRUNC and create a new tag on TRUNC named R2_0_1_PName_AMB.
  19. Development on TRUNK is still towards to RC3_0 and work is never ends…

The above rules/steps are referred to only one application, but are the same for all applications.

Please read again the first post of this series to understand the rules. I know that you will need explanations on the image, so please ask. A few important explanations:

  • Branch tags will always start with ‘BT_’
  • Release candidate prefix is ‘RC_’
  • Release prefix is ‘R_’
  • Release numbers are separated with underscore (e.g. 2_0)
  • Tags that are not releases but are related to a release candidate are using 2 dashes ‘–” (e.g. 2_0–1)

Using this procedure we can go back to any release of PName that we want (using the branch tags) and continue the branch with a quick fix, or even create a new branch of branch.

I know that there are better and more elegant procedures, but this is just the procedure that we follow and works in our small development team. It is simple, without any additional tools, but needs strong communication between developers, an issue tracker (we use mantisbt) and require developers always follow the rules. Also, you many need a wiki (we use MediaWiki) to record all the tags for each application. The release notes are recorded into the issue tracker.

Without rules and release management procedure, even a small application can be very complex after a few production releases. Always define rules and be sure that are acceptable by all developers. If there is a leak in the defined procedure, then the developers will find it and apply it for sure. As now the developers are the users of the product (product = release management procedure) and users are always unpredictable.

Don’t forget to share!

Reference: Version control branching strategies 1/2 Version control branching strategies 2/2 from our JCG partner Adrianos Dadis at the Java, Integration and the virtues of source blog.

Adrianos Dadis

Adrianos is working as senior software engineer in telcos business domain. Particularly interested in enterprise integration, multi-tier architecture and middleware services. He mainly works with Weblogic, JBoss, Java EE, Spring, Drools, Oracle SOA Suite and various ESBs.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button