Skip to content
Sean R. Eddy edited this page Jan 31, 2017 · 8 revisions

HMMER has switched to using a popular git workflow that's often just called "git flow". Go read the 2010 blog post by Vincent Driessen that describes it. We will use it with three differences:

  • For historical reasons, for the time being the stable release branch is h3-master, and the H3 development integration branch is h3-develop, rather than the customary master and develop. A large development project (HMMER4) is already underway in the master branch, and that started when we were still using Subversion under an unstable-trunk policy.

  • How we manage having Infernal depending on HMMER and HMMER depending on Easel.

  • We don't mind having feature branches on origin.

In what follows, first we'll give concise-ish examples of the flow for normal development, making a release, and making a "hotfix". A summary of the principles and rationale follows the examples.

Normal development

Generally, for any changes you make to our code, you will make on a feature branch, off of h3-develop. So first you create your branch:

   $ git checkout -b myfeature h3-develop            

Now you work, for however long it takes. You can make commits on your myfeature branch locally. Working with a local branch on your own machine will often be sufficient. But if you want to push your feature branch up to github (origin) -- maybe you want to be able to clone it for testing on a bunch of different platforms -- you can do that:

   $ git push -u origin myfeature

When you're done, and you've tested your new feature, you merge it to h3-develop (using --no-ff, which makes sure a clean new commit object gets created), and delete your feature branch:

   $ git checkout h3-develop                     
   $ git merge --no-ff myfeature
   $ git branch -d myfeature
   $ git push origin --delete myfeature
   $ git push origin h3-develop                  

Small features: single commits can be made to h3-develop

Alternatively, if you're sure your change is going to be a single commit, you can work directly on the h3-develop branch.

   $ git checkout h3-develop                  
     # make your changes
   $ git commit
   $ git push origin h3-develop               

Big features: keeping up to date with h3-develop

If your work on a feature is taking a long time (days, weeks...), and if the h3-develop trunk is accumulating changes you want, you might want to periodically merge them in:

   $ git checkout myfeature
   $ git merge --no-ff h3-develop           

Making an H3 release

To make a release, you're going to make a release branch of the code, and of any other repos it depends on. For example, for an Infernal release, you're going to make release branches in HMMER and Easel too. You assign appropriate version numbers to each, test and stabilize. When everything is ready, you merge to h3-master and tag that commit with the version number; then you also merge back to h3-develop, and delete the release branch.

For example, here's the git flow for a HMMER3 release, depending on Easel. Suppose HMMER is currently at 3.2.1, Easel is currently at 0.2.3, and we decide this release will be HMMER 3.2.2 with Easel 0.2.4:

   $ cd easel
   $ git checkout -b release-0.2.4 develop
     # change version numbers to 0.2.4; also dates, copyrights
   $ git commit -a -m "Version number bumped to 0.2.4"

then HMMER:

   $ cd hmmer
   $ git checkout -b release-3.2.2 h3-develop
     # Change version numbers to 3.2.2; also dates, copyrights
   $ git commit -a -m "Version number bumped to 3.2.2"

Now you do your release testing, making any changes and commits you need to make. When you're done, merge to h3-master and tag it; then merge to h3-develop and delete the release branch. Dependencies get tagged twice, once for themselves (Easel 0.2.4) and one for the main package that's going to depend on them (HMMER 3.2.2):

   $ cd easel
   $ git checkout master
   $ git merge --no-ff release-0.2.4
   $ git tag -a 0.2.4
   $ git push origin 0.2.4
   $ git tag -a hmmer-3.2.2
   $ git push origin hmmer-3.2.2
     # this records that the hmmer 3.2.2 release depended on this Easel commit object
   $ git push
   $ git checkout develop
   $ git merge --no-ff release-0.2.4
   $ git push
   $ git branch -d release-0.2.4
   $ git push origin --delete release-0.2.4

and do the equivalent in HMMER, for its release-3.2.2 (in the h3-master branch) tagging it just once with 3.2.2.

Using existing releases

If you don't need a new Easel release, you can use the last release on the master branch; you just have to tag it.

   $ cd easel
   $ git checkout master
   $ git tag -a hmmer-3.2.2

Fixing bugs: "hotfix" branches

If you need to fix a critical bug and make a new release immediately, you create a hotfix release with an updated version number, and the hotfix release is named accordingly: for example, if we screwed up HMMER 3.2.2, hotfix-3.2.3 is the updated 3.2.3 release.

A hotfix branch comes off master, but otherwise is much like a release branch.

   $ cd hmmer
   $ git checkout -b hotfix-3.2.3 h3-master                 
     # bump version number to 3.2.3; also dates, copyrights
   $ git commit -a -m "Version number bumped to 3.2.3"

Now you fix the bug(s), in one or more commits. When you're done, the finishing procedure is just like a release:

    $ git checkout h3-master              
    $ git merge --no-ff hotfix-3.2.3
    $ git tag -a 3.2.3
    $ git checkout h3-develop              
    $ git merge --no-ff hotfix-3.2.3
    $ git branch -d hotfix-3.2.3


Summary of main principles

There are two long-lived H3 branches: origin/h3-master, and origin/h3-develop. The origin/master branch is an unstable H4 development branch. All other branches have limited lifetimes.

h3-master is stable. Every commit object on h3-master is a tagged release, and vice versa.

h3-develop is for ongoing development destined to be in the next release. h3-develop should be in a close-to-release state. Another package (e.g. Infernal) may need to create a release of a downstream dependency (e.g. HMMER or Easel) at short notice. Therefore, commit objects on h3-develop are either small features in a single commit, or a merge of a finished feature branch.

We make a feature branch off h3-develop for any nontrivial new work -- anything that you aren't sure will be a single commit on h3-develop. A feature branch:

  • comes from h3-develop
  • is named anything informative (except h3-master, h3-develop, hotfix-* or release-*)
  • is merged back to h3-develop (and deleted) when you're done
  • is deleted once merged

We make a release branch off develop when we're making a release. A release branch:

  • comes from h3-develop
  • is named release-<version>, such as release-3.2.2
  • first commit on the hotfix branch consists of bumping version/date/copyright
  • is merged to h3-master when you're done, and that new commit gets tagged as a release
  • is then merged back to h3-develop too
  • is deleted once merged

We make a hotfix branch off h3-master for a critical immediate fix to the current release. A hotfix branch:

  • comes from h3-master
  • is named hotfix-<version>, such as hotfix-3.2.3
  • first commit on the hotfix branch consists of bumping version/date/copyright
  • is merged back to h3-master when you're done, and that new commit object gets tagged as a release.
  • is then merged back to h3-develop too
  • is deleted once merged
Clone this wiki locally