22 January 2015

Ah, Git, our one and only and lovable version controlling system! How would we have developed software without you?

I want to share with you today the branching model we use here in Sanmark. As mentioned in the last post, our Git branching model is a little bit close to that of Gitflow.

Initializing Project and Git Repository

We start with an empty directory and create the “.gitignore” file in it before doing anything else. Then we commit it as the “Initial Commit”.

Then two more branches are created, namely “dev” and “”init”.

It is this “init” branch we use to bootstrap our projects — project creation, configurations, compulsory package installation, environment setup all goes into this branch. Usually one person (Project Lead) handles this branch. He commits soon and often to this branch and get everything ready in a matter of an hour or two.

Once done, he’ll squash all the commits in the init branch into a single commit — of which’s commit message is often “Initiate project.”.

And then merge that to dev using fast-forward method. This “Initiate project.” commit will be the second commit of the dev branch (“Initial Commit” being the first.). After that, the init branch will be deleted.

Now the project and the Git repository is initialized. We can push the branches master and dev to a remote bare repository — either a manually maintained one, or one hosted in a Git hosting solution like GitLab and GitHub –, and other team members can clone this and start contributing to the project!

Naming Feature and Bug-fix Branches

Creating Branches for Issues Reported in Issue Tracker

If we are creating a feature or a bug-fix branch based on an issue in our issue tracker, we mention that issue’s number in our branch name. And we prefix our feature branch names with “do#” — bug-fix branch names are prefixed with “fix#”.

For an example, if we have a feature request with the number 123, and a bug report with the number 149, we will create a feature branch with the name “do#123” and a bug-fix branch with the name “fix#149”.

Creating Branches without Issue Reports

If we are creating feature or bug-fix branches to do something that was not reported in the issue tracker, we prefix them with “do-” (for feature branches) or “fix-” (for bug-fix brances) and follow the prefixes with the actual name, which is written in camel-case. “do-create_login_system” and “fix-stop_redirect_loop” are examples.

Creating Feature Branches

Feature branches will always branch-out from the dev branch. Before creating a new feature branch, we make sure we have the latest dev branch available (By fetching the dev branch from our remote central repository.). Once we confirm that we do have the latest dev branch, we create our feature branch from the last commit of that branch.

Then we commit early and often

Once done, we squash all the commits of the feature branch into a single commit. We add a descriptive commit message for the squashed commit.

If we are squashing a branch created based on an issue from the issue tracker, we prefix the commit message with “#”, then the issue number, and finally the actual commit message (Eg. “#132 Create login system.”). If the branch was not based on a issue, just put the message without any prefixes.

And finally, we merge the feature branch into dev and delete the feature branch. Before doing that, we check whether dev branch has moved forward since we branched-out from it. If it hasn’t we go ahead and merge it.

What if the dev Branch has Moved Forward?

If the dev branch has move forward since we branched-out, it’ll look like this after we fetch it just after we finish our feature-branch.

If this happens, we have to rebase our feature branch onto the latest dev.

Now we can fast-forward merge our feature branch into dev, and delete the feature branch.

Creating Bug-fix Branches

Bug-fix branches are almost always branched-out from the master branch, unless the reported bug is not yet found in the code in the master branch, and only found in the dev branch — in which case the branch for fixing that bug will be branched-out from dev.

Changes are committed early and often, all commits are squashed into one at the end of the bug-fix process. The issue number should be a prefix in the commit message of the squash commit, if the branch was based on an issue from the issue tracker.

If the bug-fix branch was branched-out from master, it’ll be merged into both master and dev branches. Merge commits are created (Non-fast-forward merge method is used.).

If the bug-fix branch was branched-out from dev, it’ll be merged into the dev branch just like a feature branch.

Merging into master Branch

Only production ready code will be merged to master branch. Only dev branch and bug-fix branches will be merged to master branch. Merges into master branch will always be non-fast-forward. Commit messages of the merge commits will be version numbers (Read the previous post “How We Version Our Code“.).