Skip to content
Travis Wheeler edited this page Jun 7, 2019 · 3 revisions

git workflow

NINJA uses a popular git workflow that's often just called "git flow". Go read the 2010 blog post by Vincent Driessen that describes it.

Here are examples of the flow for normal development, making a release, and making a "hotfix".

Normal development

You will usually make on a feature branch, off of develop. So first you create your branch:

   $ git checkout -b myfeature develop            

Now you work, for however long it takes. You can make commits on your myfeature branch locally, and/or you can push your branch up to the origin and commit there too, as you see fit. 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 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, and if the develop trunk is accumulating changes you want, you might want to periodically merge them in:

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

Making a release

To make a release, you're going to make a release branch of the code. You assign an appropriate version number, test and stabilize. When everything is ready, you merge to master and tag that commit with the version number; then you also merge back to develop, and delete the release branch.

For example, here's the git flow for a NINJA release. Suppose NINJA is currently at 2.1, and we decide this release will be NINJA 2.2:

   $ cd ninja
   $ git checkout -b release-2.2 develop
     # Change version numbers to 2.2; also dates, copyrights
   $ git commit -a -m "Version number bumped to 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.

   $ cd ninja
   $ git checkout master
   $ git merge --no-ff release-2.2
   $ git tag -a 2.2
   $ git checkout develop
   $ git merge --no-ff release-2.2
   $ git branch -d release-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 NINJA 2.2, hotfix-2.3 is the updated 2.3 release.

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

   $ cd ninja
   $ git checkout -b hotfix-2.3 -master                 
     # bump version number to 2.3; also dates, copyrights
   $ git commit -a -m "Version number bumped to 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-2.3
    $ git tag -a 2.3
    $ git checkout develop              
    $ git merge --no-ff hotfix-2.3
    $ git branch -d hotfix-2.3


Summary of main principles

There are two long-lived branches. All other branches have limited lifetimes.

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

develop is for ongoing development destined to be in the next release. develop should be in a close-to-release state. 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 master, develop, hotfix-* or release-*)
  • is merged back to develop 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 develop
  • is named release-<version>, such as release-2.2
  • first commit on the 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-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