Our Processes Around Git and GitHub

This post was inspired by some onboarding notes that Sana took to document our process. Thanks Sana!

This is a reference for some processes around the following:

GitHub Issues

We use GitHub issues to organize our tasks, whether big or small or unknown in scale.


A goal is nothing more than an issue that is meant to collect other sub-issues. In our case, we work in quarterly goals, but you can divide time however is most useful to you.

We like to attach a label, such as goal:primary, to such issues.

Label on Goal

When we open issues that address the goal, we can tag the goal’s issue number (in this case, 1) in the smaller issue’s description. Just by writing “#1”, GitHub links the two.

Tag Issue Number

And now when we look back at the bigger goal-issue, we see a reference to the smaller issue! You can see that when the smaller issue is closed (by completion or otherwise), the green Open badge will become a red Closed badge. This turns this view into a checklist of sorts.

Issue Added to Goal

Milestones and milestone planning

In addition to the above, we use GitHub Milestones to plan out 2-week cycles, assigning each issue to a milestone as we determine we want to address it.

We have a milestone planning meeting every two weeks in which we (briefly) review the work of the prior two weeks. (This usually involves a fair amount of self-congratulation, which is very healthy when warranted.) The main activity of the planning session is to identify issues that we want to work on next. There should be a healthy mix of core issues related to goals (as described above) and other issues (including bugs!) that may not be categorized. We also assign issues to contributors. For this we’ve tended to assign one solo issue per contributor and a larger, more thought-provoking and decision-heavy issue for pairing on.

Git Workflow

The following commands make use of the aliases outlined below.

We name our branches in a generic way, preceding the issue number with fix-. Therefore, if we want to work on getting users to pause before commenting, we can work on branch fix-002:

1. Start from the production branch

g co production

2. Pull any new changes residing on production

g pull

3. Create your feature branch

g co -b fix-002

4. Create an empty commit, push the branch, submit a pull request

g commit --allow-empty -m "First Commit"
g push -u origin fix-002
g pr

5. Commit locally

When you’ve written some awesome code!

g add . 
g commit 

And add a minimally-meaningful commit message. These will end up squashed in step 6.

Optional 5a. Giddy up!

g up

6. Rebase with production

When your feature is done and ready for deployment! When we rebase and squash commits, we like to write meaningful commit messages and as a final line, we’ll include: Fixes #2. GitHub picks up on this and automatically closes the issues when this commit is merged to production.

g ir

7. Locally merge fix-002 on production

g co production
g pull
g merge fix-002

8. Push to production

g push

9. Delete your branch both locally and on GitHub

g rmb fix-002

Aliases and shortcuts used above

In ~/.gitconfig add:

  co = checkout
  up = !git fetch origin && git rebase origin/$DEFAULT_BRANCH
  ir = !git rebase -i origin/$DEFAULT_BRANCH
  pr = pull-request
  rmb = !sh -c 'git branch -d $1 && git push origin :$1' -

In ~/.bash_profile (or equivalent) add:

alias g=git


Step 1: We’ve opted to use a branch called production instead of git’s default, master. This decision was made because “production” seems to convey the purpose/destiantion of the branch more fully and “master”, as a word, has problematic baggage.

Step 4: This is optional and not everybody on the team opens an empty pull request. You’re welcome to skip this step and run g push -u origin fix-002; g pr making your first meaningful commit.

Step 4, on awesomeness: Doesn’t have to be awesome. Most code isn’t awesome.

Step 5a: “Giddy up” is what I affectionately call the process of updating your local branch with whatever fabulous code has been committed to production in the meantime.

Step 6: This is the part where we squash all of our commits down to 1 per issue resolved.

Step 9: This is a cool alias that deletes your local and remote (GitHub) branches. Don’t worry, it’ll yell at you if you have unmerged code!