Git Workflow

Posted September 09, 2014         « Previous post     Next post »

Now that we’ve created the GitHub Repository for the NVM Library, here’s a more detailed description of the git workflow we’ve chosen. The basic idea is:

  1. Current development happens on the master branch
  2. Releases are created periodically by tagging
  3. Release branches are usually not used (master contains everything) unless it is decided that a patch to a previous release is needed, at which point a release branch will be created for that work.
  4. All changes are done using the common GitHub fork and merge model, where GitHub users fork the repository, make their changes, and submit pull requests.

Here’s a walk-through of the common development workflow, where changes end up on the master branch.

Using a local feature branch

git overview

As shown in the above picture, the master branch moves forward in time, collecting commits (shown as the small circles) and periodically tagging releases. In the above example, one user has forked the repo and has created feature-branch-A locally to work on a change. At the same time, another user has forked the repo to work on feature-branch-B locally. Forking and creating a local feature branch are the first steps in development and are done like this:

$ git clone
$ cd nvml
$ git remote add upstream git://
$ git checkout -b my-feature-branch

Developing and merging locally

Now that you have your local feature branch, do your development with frequent commits recommended. Be sure git is configured with your correct name and email address:

$ git config --global "Firstname Lastname"
$ git config --global ""

Now you can work on your changes locally, committing them to your local feature branch:

edit files, run tests...
$ git add ...
$ git commit ...
repeat as necessary...

Please follow the common conventions for git commit messages:

For example, here is a properly-formatted commit message:

doc: fix code formatting in man pages

The indentation in code examples contained in the man pages
was not formatting correctly due to a bug in groff.  This
fix avoids the issue by using man2html instead of groff.

Ref: pmem/issues#1


At convenient points in your development, you will want to re-sync with any changes that have happened in the upstream repo. Do this using git rebase rather than git merge.

$ git fetch upstream
$ git rebase upstream/master # or upstream/0.1 if patching release 0.1, for example

Before submitting changes

Before asking for your changes to be merged, you are expected to perform these steps at a minimum:

# from top-level of repository...
$ make cstyle
$ make
$ make test
$ cp src/test/ src/test/ # edit as necessary
$ make check

We also require all the above to pass using the clang compiler:

$ make clobber
$ make CC=clang CXX=clang++
$ make CC=clang CXX=clang++ test
$ make CC=clang CXX=clang++ check

Please add the appropriate unit tests to verify new features you’ve added.

Please note that the C++ compiler must support the C++11 standard.

Cleaning up your commits

If you’d had a good number of uninteresting commits, such as those that fix typos or head down a wrong path that you later discarded, you should consider squashing those commits into a cleaner set of commits. The command git rebase -i is a very useful tool for this. For example:

$ git fetch upstream
$ git rebase -i upstream/master

The above rebase command will put you in the editor with a list of all the commits you made on your feature branch. This is a very powerful operation with lots of possibilities – too many to describe here, but a quick remind may help you use it. Say you had four commits but two of them were annoying typo changes that you’d rather just squash away. You’ll see the four commits in the edit like this:

pick 60d3a42 subsystem: this is the first commit message
pick 7c970de subsystem: oops, stupid typo
pick d951f42 subsystem: this is the second commit message
pick dc80ecd subsystem: oops, another stupid typo

Let’s say you want to convert this to two commits, folding the typo fixes into the commits before them. Change the word pick to squash for the commits being squashed – actually, you only need the letter s, like this:

pick 60d3a42 subsystem: this is the first commit message
s 7c970de subsystem: oops, stupid typo
pick d951f42 subsystem: this is the second commit message
s dc80ecd subsystem: oops, another stupid typo

When you write and exit the editor, git will allow you to edit and clean up the commit messages for each set of squashed commits (twice in this example).

Note: if you haven’t used rebase -i before, you should make a copy of your repo before doing this, just in case!

Submitting your change

Now that you’ve your changes are cleanup and fully tested, you’ll want to push them back to your fork of the repo on GitHub:

$ git push origin my-feature-branch

And finally, send the changes back to the original NVM Library repository:

Posted by @andyrudoff         « Previous post     Next post »