Skip to content
Sean R. Eddy edited this page Nov 1, 2017 · 8 revisions

HMMER uses 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 a couple of minor differences:

  • How we manage having HMMER depend on Easel and Infernal depending on HMMER. That is, a HMMER release packages Easel, and an Infernal release packages both HMMER and Easel, so we coordinate development/release of the three git repositories.

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

We have three main branches:

  • master: stable HMMER3 releases. Protected; only admin can push to it.
  • develop: HMMER3 development.
  • h4-develop: HMMER4 development.

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 develop. So first you create your branch:

   $ git checkout -b myfeature develop            

HMMER3 feature branches (off develop) can be named anything informative. HMMER4 feature branches (off h4-develop) are prefixed h4-, such as h4-myfeature.

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 develop (using --no-ff, which makes sure a clean new commit object gets created), and delete your feature branch:

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

Small features: single commits can be made to develop

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

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

Big features: keeping up to date with develop

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

   $ git checkout myfeature
   $ git merge --no-ff 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, a HMMER admin merges the release branch to master and tags that commit with the version number; then you also merge the release branch back to 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"
   $ git push -u origin release-0.2.4

then HMMER:

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

Now you do your release testing, making any changes and commits you need to make. When you're done, merge to master and tag it; then merge to 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 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 Easel 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 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 master              
    $ git merge --no-ff hotfix-3.2.3
    $ git tag -a 3.2.3
    $ git checkout 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: master and develop. The h4-develop branch is an unstable H4 development branch. All other branches have limited lifetimes.

master is stable. Every commit object on master is a tagged release (though possibly for Infernal, not HMMER itself), and vice versa.

develop is for ongoing development destined to be in the next HMMER3 release. 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 develop are either small features in a single commit, or a merge of a finished feature branch.

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

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

HMMER4 feature branches come off h4-develop, and are prefixed by h4-; for example, h4-myfeature.

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

  • comes from 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 master when you're done, and that new commit gets tagged as a release
  • is then merged back to develop too
  • is deleted once merged

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

  • comes from 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 master when you're done, and that new commit object gets tagged as a release.
  • is then merged back to develop too
  • is deleted once merged