The StreetHawk code is broken up into multiple repositories, the backend webapp, the iphone UI, the iphone API layer that accesses the database and handles all logical/operational aspects of the iPhone app, the android app (with the same breakdown), tools etc. Up until now all code has been checked straight into the “default” branch (HEAD). Going forward we have decided to adopt the following scheme inspired by and based on workflows prescribed by Steve Losh and Vincent Driessen. I would particularly recommend Steve’s tutorial on branching which was very very critical in helping me understand the general branching techniques in mercurial. If anything this post is a summary of their article to act as a “manual” for ourselves and is prone to change given all the nasties we may find in the future.
Firstly a recap of some of the branching and tagging commands that we will use later on.
Creating a new branch
# Get into the branch from which the new branch is to be created. # This would usually be "default" if it is a new future development or "stable" if a bugfix hg checkout <parent_branch_name> # Create the new branch hg branch <branch_name> # commit it - at this point it is a local branch hg commit -m "Added <branch_name> branch" # push it to the server to create a remote branch hg push -b <branch_name> --new-branch
Merging from another branch
Time to time you may find the need to merge from another branch. This is simple. This will ensure the source_branch is merged into the target_branch. NOT the other way around (even after you do a push).
# Get into the branch "into" which you want changes merged hg checkout <target_branch> # merge from the source branch hg merge <source_branch>
Closing a branch
Some times (quite often actually) you may find branches created unnecessary. To remove the branch:
# Get into the branch you want to close (by now you can see the general pattern here!) hg checkout <target_branch> # close it hg commit --close-branch
Tagging a branch
Tag a branch on every release. Simply do:
# Get into the branch you want to close hg checkout <branch_name> hg tag <tag_name>
The convention used here is: <PUBLIC_VERSION>_<PRIVATE_VERSION>
PUBLIC_VERSION = <MAJOR_VERSION>_<MINOR_VERSION>_<BUGFIX_NUMBER> PRIVATE_VERSION = <PURPOSE>_<BUILD_NUMBER> MAJOR_VERSION - indicates a back incompatible version MINOR_VERSION - new features added BUGFIX_NUMBER - bugfixes updates PURPOSE - purpose of the build - eg "APPSTORE", "TESTFLIGHT", "ADHOC" etc... BUILD_NUMBER - The build attempt for a given PUBLIC_VERSION and purpose.
Branching and Release Workflow
In this scheme we have the following branches:
“default” – This the dev branch that contains all the checked in features and bugfixes that are *ready* to go into the next stable release.
“stable” – The branch that tracks the stable production releases. Code from “default” is always merged into stable before a release.
“feature_xyz” – New features are added and developed on their own branches (eg feature_camera, feature_location etc) and merged into “default” upon completion but NOT before they are ready to be accepted into are release. So only merge these into default when they are ready for the next release.
“bugfix_xyz” – Similar to the feature branches but these are usually branched from stable and then merged back into both “default” and “stable”. These are usually urgent changes/fixes to be applied on released code.
Given the above branches, an appropriate workflow would contain the following roles (could be the same person):
Developer - Is responsible for adding new features and bug fixes and most likely would be adding to “default” or “feature” branches (or onto stable via bugfix branches).
# get into default hg checkout default # do an update hg pull -u # create the feature branch hg branch feature_awesome # commit it - at this point it is a local branch hg commit -m "Added <branch_name> branch" # add the awesome feature # do a few commits A, B, C # push it to the server to create a remote branch ONLY # when ready for release hg push -b <branch_name> --new-branch
Release Creator/Owner – Creates new stable production releases. Note DO NOT do a rebase here as that would detach local changes. We specifically want to keep track of all past activity.
# get the latest on all branches hg pull -u # get into stable hg checkout stable # Merge default into stable to get all production ready # features into stable hg merge default # Do the testing and when time to release, tag it (you are still in stable) hg tag <tag_name> # push the new tag hg push