Git branching strategy
I'm preparing a set of materials for a batch of interns whom I will be mentoring for a software development project.
One of the things that they will be doing is to check out an existing codebase to work on. To do that, they need to know Git.
I'm quite certain that the basics of checking in and out code is no problem for them if they have any Github profiles. However, every organization has its own conventions and requirements when it comes to maintenance of their codebases. This post documents my preferences in code maintenance.
Branching strategyโ
When taking on a new codebase, one of the first things to understand is the branching strategy used by the organization. A branching strategy isn't a Git command or function. Rather it is a set of conventions that determine the approach to handle code changes in terms of code releases, bug fixes and new feature development. The things to consider are the convention for creating and naming of new branches, and the guidelines for when and how to merge changes.
There are several popular ones out there:
One factor affecting the choice of strategy is the size of the team. The size of the team has a direct (but not necessarily proportional) bearing on the number of concurrent branches. It is important to be judicious about selecting the suitable strategy. Each strategy yields different benefits but also introduces additional overhead.
A strategy perfect for a team of hundreds is likely to be too onerous for a team of three.
Some of the strategies above are also outdated in the sense that they do not lend well to the modern strategies of continous integration/continuous deployment (CI/CD).
For a small team of less than five, here are my heuristics (Maybe I should call it SimpleFlow ๐ค):
- A
production
branch should be branched off themain
(ormaster
) branch. - All releases are made on the
production
branch. - Each release should be accompanied by a tag.
- This implies that the
main
branch contains the latest, tested changes. - Feature development should take place on branches based off the
main
branch - these are called feature branches. - Feature branches should rebase from the
main
branch frequently. - Feature branch should be merged back into the
main
branch when development is done. - Hotfixes should only be made on branches based off the
production
branch and merged back intoproduction
for release.
By keeping all releases on the production
branch only, any CI/CD pipeline can be honoured during deployment.
Exampleโ
Here is an example scenario:
Say Alice is tasked to create a new feature for users to select one of a few preset avatars. She checks out the codebase which defaults to the main
branch.
$ git checkout git@github.com:coy-project
$ cd coy-project
She then creates a new branch preset-avatar
.
$ git checkout -b preset-avatar
She starts work in this branch.
Halfway through her work, she receives instructions to investigate a reported bug in the production system. She stashes any outstanding work in her branch before switching to the production
branch to start investigation work. She creates a new branch hotfix-broken-image
to start her code changes. (Before creating the new branch, she should make sure to have the latest commits from production
as well.)
# In `preset-avatar` branch.
$ git stash # Put her current work away.
$ git checkout production
$ git pull
$ git checkout -b hotfix-broken-image
She makes the necessary code changes to fix the bug. Then she commits the code to the hotfix branch. Before she makes a pull request (PR) to the production
branch, she pulls in the changes one last time. There should not be any more changes to production in this scenario, but edge cases can occur.
$ git commit -m "Fixed broken link to image."
$ git checkout production
$ git pull
$ git checkout hotfix-broken-image
$ git rebase production # Only if there are new changes from `git pull`
The project lead will review the changes. Notice there isn't a command for PRs. PRs are artefacts of the centralised service (i.e. the likes of Github and Gitlab) that provides the centralised Git service - they're not part of the core Git functionality.
After the changes are approved, she will merge the changes into the production
branch. In some cases, changes to the production
branch are restricted to project leads, so only the project leads can merge the pull request.
$ git checkout production
$ git merge hotfix-broken-image
Regardless of who merges the hotfix into the production
branch, Alice goes back to continue to her work on the preset-avatar
branch by restoring the changes that she had stashed away earlier.
$ git checkout preset-avatar
$ git stash pop # Restore the work she previously put away.
From this point on, she continues her work.
Identityโ
One other thing that I require collborators to do is to set the name and email of the Git identity that is registered in the Git history.
$ git config user.name "<Your name here>"
$ git config user.email <your@email.com>
This is so that the Git history reflects clearly who made which commits.
I want to avoid entries that look like this when I run git log
:
commit 012bf3d06e6f707a23b1786c9bd94f59f851d576
Author: juju <ilovejuju@MacBook-Air.local>
Date: Thu Jul 7 08:48:16 2022 +0800
made code changes
The name and email should be the formal identity registered with the company.
Conclusionโ
This article covers the high-level, strategic approach that I've used for small projects.
The next few articles will cover the more strategic, tactical uses of Git.