Did you ever came across the situation of not being able to trace-back accurately which version/configuration of software was released and what the history was? Sooner or later every developer will get into this position. When this occurred to me I looked for solutions in books and on the internet and combined it into a “Simplified Git Release Strategy”. Git is the version control system that is used to implement this strategy. It is required that you have some basic understanding of Git. If this is not the case you could take a look at the free ebook Pro Git by Scott Chacon and Ben Straub (2nd edition, 2014).
This post proposes the strategy as an example, without going into detail of configuration management or the release verification process. It is inspired on A successful Git branching model from Vincent Driessen and altered to make it fit in a small development team for a research department. The main requirements were traceability and to minimize the (administrative) overhead.
The first part of the post will explain the used terminology and the layout of the repository, followed by steps of the strategy and ends with some personal experiences.
Git is the version control system, the repository is where the code is stored. commit is the command and action that stores the actual data (e.g. source-code) to the repository. Data is committed in a branch, the branch can be seen as a separated section in the repository and all branches are related to the master branch in a(n) (in)direct way. With merge two branches are weaved back together, both branches will by default exist afterwards. Since commit will store it in the local repository on your pc, with push it will be made available in the remote repository. You and other developers can pull it from the remote repository to stay up to date. To give a certain commit an easy reference a tag can be used. These are the basics in a nutshell. One more advanced command is used in the release strategy, called cherry-pick. This is nothing more than a selective merge, in which the user chooses intermediate commits of one branch that are copied to the other. Later on this will be made clear with a figure.
Layout of the repository
The typical layout of a repository is made up of a master branch, used as the release branch. The branch where the actual work is conducted in, is called the develop branch. When working on the development branch it can be convenient to develop certain features in a separate branch called feature branch. The feature when finished can be merged into the main development branch. When the development work is ready to be released we can start using the “Simplified Git Release Strategy”.
Before the start of the actual release process make sure all your work is committed in the develop branch and that there are no uncommitted files left in the local repositories (Step 1).
Switch to the release branch (i.e. master branch) with the command git checkout <branch> (Step 2). merge the committed work of the develop branch into the release branch called master (Step 3).
Now all the development work is transferred to the release branch. Maybe some administrative work needs to be conducted to finish up the release. This work needs to be committed to the release branch. It is a good habit that if the work consists of multiple sub tasks, to commit them separately, for a reason that will become clear in Step 6. When ready for release, a release script can be executed. This script can for instance gather source-code, documentation, binaries and combine them into a package.
The generated release files need to be committed (Step 4). When finished this official release commit can be tagged in order to find it back easily (traceability) (Step 5).
With the command git tag <tagname> the last commit is tagged. By default git push does not automatically pushes the tag to the remote repository, it is important to give the following command after tagging git push origin <tagname>. This makes sure that the tag is available both in the local and remote repository. Now the release is easy traceable.
In general, there should not be much work in the release branch that needs to be committed back into the develop branch. However, if this is the case cherry-pick can be used. Every commit has a reference called hash, that can be used to indicate which commit needs to be merged (see Step 6).
In the figure of Step 6 the hashes are simplified, but normally look something like this ab8226728ea7d592acc79b36843a412cdf3fd5c8d. Make a list of the commits that need to be cherry picked and go from the master branch to the develop branch, with the command git checkout develop. Make sure that there are no uncommitted files left before switching. When switched use git cherry-pick <A> <B> where A and B stand for the hashes to merge them in the development branch. The number of hashes given can be one or more.
Now it is all finished: back to developing!
Based on my experiences using this strategy there are some considerations:
If during work in the release branch, at Step 3 or later, it becomes obvious that there is need for development work before it can be released. It is better to switch back to the develop branch and conduct the work there and later on restart at Step 1.
The main reason for conducting “real” development work in the develop branch is to not contaminate, i.e. add additional commits, to the release branch with development work for traceability reasons. Also the development work done in the release branch needs to be merged back in the develop branch, which can be cumbersome.
This also brings us back to the point, after Step 3, that if necessary, only administrative work needs to be conducted in the release branch. This administrative work should be divided up in small commits, so that if necessary to merge back some work in the develop branch it can be kept to a minimum, in order not to contaminate the release or develop branch.
Reason for tagging the releases, is to make it easier to trace back the history of the development work when necessary. If certain development work and a release need to be compared it can be referenced via this same tag. For instance the development environment Eclipse with the plugin EGit lets you easily compare your current work and a Tag in the editor itself.
So far the Simplified Git Release Strategy, the six steps mentioned made it easy and quick to release software in a research setting with less overhead. If there are any questions on this approach please feel free to leave a comment under this blog.