How we use git and Github to build Nexu.mx

Javier Sagastuy
#NexuDev
Published in
6 min readAug 24, 2017

Developing new software and efficiently collaborating with other team members is not easy to the newcomer to a distributed version control system. Hell, even a skilled developer with knowledge of git, can struggle to make his current git workflow fit into a new team.

After seeing our repos heading towards quantum entanglement, I decided action was needed. I dug deep into best practices for using git and Github, and looked into several team’s workflows without finding something that would work for us.

Quantum entanglement: Bear in mind, none of these branches, or merge commits were done intentionally. They simply resulted from forks due to simultaneous work based off the same commit.

The git-flow, proposed by Vincent Driessen seemed a bit of an overkill for our needs at the time. Don’t get me wrong, I think it is great. I just think that it might baffle developers who are just starting to get a hang of how git works and believe it works best with larger, more complex, yet more structured teams than what we had at Nexu.mx at the moment.

I later came across the Github flow (TL;DR). Scott Chacon explains how Github uses git to build Github using a simplified version of the git-flow. We derived our workflow from the Github flow, albeit with some small modifications and configuration tips, to help developers get on board with git and Github at Nexu quickly.

The Nexu-git-flow

1. Master is always deployable

This is the core of the Nexu-git-flow. master should always be in a deployable state. Code in master is in production or will be in production soon. This branch does not allow for any direct modifications. To achieve this, we leverage protected branches on Github.

Branch protections allow us to prevent anybody on the team from working directly on master. New code must come from a development branch and always be reviewed before being merged into master. We set up our master branches to be protected using the following settings:

  • Require pull request reviews before merging
  • Require status checks to pass before merging
  • Require branches to be up to date before merging

We’ll eventually also add a restriction to require Continuous Integration (CI) tests to pass before merging.

2. Development branches

To start coding, Nexu developers create new branches from the latest commit on master. New code goes there and we agree to commit early and push often, so everybody can get their hands on new code ASAP.

To keep history as clean as possible, avoid unwanted merges, and make typing commands a bit faster, we encourage developers to use the following global git configuration:

Specifically, pay close attention to the branch.autosetuprebase and pull.rebase options. This basically sets up rebasing for new branches automatically and makes every pull from the repository rebase your local changes, instead of forcing a merge caused by diverging commits on the same branch (a problem often encountered in our early days).

New branches should be named descriptively. Names should be short, uncapitalized, and hyphenated to keep our branch naming style consistent. To create new branches, correctly set up branch tracking, and push them to Github, we encourage developers to adhere to the following workflow:

$ git checkout master
$ git pull
$ git checkout -b development-branch
$ git push -u origin development-branch
... start commiting and pushing ...

3. New commits go in development branches

We always create new commits on development branches and never on master. Rewriting commit history is allowed on development branches, taking the necessary precautions not to affect anybody else’s work on that branch. Force pushing a development branch should be avoided, but is allowed when it significantly improves commit history on the branch.

Workflow in a new branch looks as follows:

$ git checkout development-branch
$ git pull
... local changes ...$ git commit -m “Adds certain functionality”
$ git pull
$ git push

Pay special attention to commit messages. A commit message should be short, descriptive and complete the sentence This commit ______ . This means the first word of a commit is always a present tense verb in third person singular form (Grammar Nazi much?). We always capitalize the first word of a commit message and never punctuate them. This maintains a consistent style when going through git logs.

4. Code review in pull requests

At the beginning, we struggled for a way to review code. Going over each new commit a developer made was hell. Github provides the ideal environment to review other developer’s code: Pull Requests. We just wish we’d learned about it sooner.

Once we’ve pushed code on our development branches to Github, we simply create a new Pull Request (PR) on the Github web interface, specifying master as the base branch, and our development branch as the compare branch.

We then go on to set assignees to indicate people who should also work on that PR; reviewers to indicate who you want to review your code; and a milestone to indicate the sprint the PR belongs to.

PRs allow a conversation to take place while reviewing code and provide a timeline of changes to the branch to be merged. Furthermore, branch protections on master block merging until at least one approved review is obtained and the branch is up to date with master.

5. Merging Pull Requests into master

#NexuDev committed to not only requiring one approved review on the branch, but requiring approved reviews from a majority of team members before merging a PR; unless it is a simple hotfix which urgently needs to be deployed. This has helped us improve the quality of our code drastically and make developers actively involved in features they might not have been originally assigned. Of course, this might not scale well for a larger team. When that happens, we’ll most likely split the team into development pods, each of which would follow the same workflow in an independent, yet coordinated fashion.

As mentioned before, at this point we plan to add a CI system to perform additional automated checks to the new code to be merged into master. A CI system would detect violations to our Styleguide or broken Unit Tests. Github provides the functionality to protect master from merges which do not meet the CI system’s criteria.

To merge a PR which has met the requirements, we simply hit the merge button on Github’s web interface. We always “create a merge commit” and never “squash and merge” nor “rebase and merge”. This further helps us keep commit history as clean and understandable as possible.

6. Changes to master should always be immediately deployed

Now our new feature has been merged into master in our central repository, and assuming we stick to the first rule, we should deploy this new feature ASAP. Assuming master will be immediately deployed better ensures code quality and discourages developers from trying to quickly merge buggy code.

Now that’s more like it! Development branches are created intentionally and commit history is easy to follow.

In a nutshell (or TL;DR)

  1. Commits on master should always be deployable.
  2. New work goes in development branches off of master .
  3. Development commits should be pushed to Github often, so the rest of the team can see your code.
  4. PRs are used to collaborate, discuss and improve the quality of the code to be introduced to master .
  5. PRs are merged into master via a merge commit, but only after required status checks pass.
  6. master should be deployed to production ASAP.

That’s about it! We believe this workflow is simple yet structured enough to help developers with the on-boarding process. It can easily be extended and adapted in many ways. Furthermore, this workflow integrates wonderfully with our deployment process.

So far, we’ve simply explained the development workflow at Nexu-mx using git and Github. But what about deployment? In part 2, I’ll give you a peek into how the Nexu-git-flow comes into play with our deployment process using Heroku, which is pure developer bliss.

--

--

Javier Sagastuy
#NexuDev

Computer engineer, applied mathematician, world traveler, skier, former #NexuDev Scrum Master