You are on page 1of 12

Git Branch Strategy and Best Practices

Abstract: This document helps to develop, track, manage and maintain the source code and
other development artefacts in a decentralized way of managing and a centralized way of
maintaining the product delivery artefacts such as source code by adhering to the best
practices and governance standards on Git repository. Also it helps to execute an
uninterrupted way to build and deploy to the run time set up by means of pull and push
mechanism that is channelized to the pre-set CI/CD configurations as per the DevSecOps.
Since every code and configurations are the intellectual property of the organization, it is our
responsibility to maintain confidentiality and enable software delivery operations within the
organization.

Why Git: As a consequence of its simplicity and repetitive nature, branching and merging
are no longer something to be afraid of. Version control tools are supposed to assist in
branching/merging more than anything else. In particular, Git helps developers collaborate
on code with teammates; combining powerful features like commits and branches with
specific principles and strategies helps teams organize code and reduce the time needed to
manage versioning.
Of course, every developer and development team is different, with unique needs. Here is
where a Git branching strategy comes in.

Git Branch Strategy: In order to facilitate two or more than two product development
members to parallelly develop the code or do the peer programming, enabling multiple
releases, features, hotfix and over all expedite coding and development of the product in a
federated way, the branching strategy is key to the development and plays a significant role in
transforming and accelerating the continuous development and continuous improvements. In
a nutshell the GitHub flow branching strategy is a relatively simple workflow that allows
smaller teams, or web applications/products that don’t require supporting multiple versions,
to expedite their work.

While working with the GitHub branching strategy, there few steps one must adhere to
ensure you maintain good code.
 Any code in the main branch should be deployable.
 Create new descriptively-named branches off the main branch for new work, such
as feature
 Commit new work to your local branches and regularly push work to the remote.
 To request feedback or help, or when you think your work is ready to merge into the
main branch, open a pull request to do the forking.
 After your work or feature has been reviewed and approved, it can be merged into the
main branch.
 Once your work has been merged into the main branch, it should be deployed
immediately or enable the auto pull for the deployment by means of build and
deployment configurations in the pipeline i.e CI/CD.

Above steps to be followed as a standard practice by the entire development/review


team.

The Benefits of Git Branch:


1. The various types of branches make it easy and intuitive to organize your work.
2. The systematic development process allows for efficient testing.
3. The use of release branches allows you to easily and continuously support multiple
versions of production code.
The Challenges of Git Flow:
1. Depending on the complexity of the product, the Git flow model could
overcomplicate and slow the development process and release cycle.
2. Because of the long development cycle, Git flow is historically not able to support
Continuous Delivery or Continuous Integration.

The main idea behind the Git flow branching strategy is to isolate your work into different
types of branches. There are five different branch types in total:
 Main/Master/Origin
 Develop
 Feature/Substream
 Release
 Hotfix
The two primary branches in Git flow are main/master/origin and develop. There are three
types of supporting branches with different intended purposes: feature or substream,, release,
and hotfix.

The main branches: As described in the below diagram,

The central repo holds two main branches with an infinite lifetime:
 master
 develop
The master or main (lets refer as Master here on) branch at origin should be familiar to every
Git user. Parallel to the master branch, another branch exists called develop. We
consider master to be the main branch where the source code which is production ready
and always reflects as in delivery state.
We consider develop to be the main branch where the source code of HEAD always reflects
a state with the latest delivered development changes for the next release. In industry terms
it is also referred as the “integration branch”. This is where any automatic nightly builds are
built and initiated from.
When the source code in the develop branch reaches a stable point and is ready to be
released, all of the changes should be merged back into master somehow and then tagged
with a release number. How this is done in detail will be explained further on.
Therefore, each time when changes are merged back into master, this is a new production
release by definition. We tend to be very strict at this, so that theoretically, we could use a
Git hook script to automatically build and roll-out our software to our production servers
every time there was a commit on master.

Supporting branches: Next to the main branches master and develop, our development


model uses a variety of supporting branches to aid parallel development between team
members, ease tracking of features, prepare for production releases and to assist in quickly
fixing live production problems. Unlike the main branches, these branches always have a
limited life time, since they will be removed eventually.
The different types of branches we may use are:
 Feature branches
 Release branches
 Hotfix branches
Each of these branches have a specific purpose and are bound to strict rules as to which
branches may be their originating branch and which branches must be their merge targets.

Feature branches: The feature branches are to be created with following protocols.

It may branch off from:


develop
But it must merge back into:
develop
Branch naming convention:
anything except master, develop, release-*, or hotfix-*
Feature branches (or sometimes called topic branches) are used to develop new features for
the upcoming or a distant future release with specific tags associated with it. When starting
development of a feature, the target release in which this feature will be incorporated may
well be unknown at that point. The essence of a feature branch is that it exists as long as the
feature is in development, but will eventually be merged back into develop (to definitely
add the new feature to the upcoming release) or discarded (in case of a work around or
catastrophic circumstances or disappointing experiment).
Please note that Feature branches typically exist in developer repos only, not in master or
origin.

Creating a feature branch: 


When starting work on a new feature, branch off from the develop branch.

$ git checkout -b feature develop


Switched to a new branch "feature"

Incorporating a finished feature on develop:


 
Finished features may be merged into the develop branch to definitely add them to the
upcoming release:
$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff feature
(Please give the summary of changes)
$ git branch -d feature
Deleted branch feature
$ git push origin develop

Please note, the “--no-ff” flag causes the merge to always create a new commit object, even
if the merge could be performed with a fast-forward. This avoids losing information about
the historical existence of a feature branch and groups together all commits that together
added the feature.
In the latter case, it is impossible to see from the Git history which of the commit objects
together have implemented a feature—you would have to manually read all the log
messages. Reverting a whole feature (i.e. a group of commits), is a true headache in the
latter situation, whereas it is easily done if the --no-ff flag was used.

Yes, it will create a few more (empty) commit objects, but the gain is much bigger than the
cost.

Release branches: 
May branch off from:
develop
Must merge back into:
develop and master
Branch naming convention:
release-*
Release branches support preparation of a new production release. They allow for last-
minute work around and changes to be incorporated. Furthermore, they allow for minor
bug fixes and preparing meta-data for a release (version number, build dates, etc.). By doing
all of this work on a release branch, the develop branch is cleared to receive features for the
next major releases.
The key moment to branch off a new release branch from develop is when develop (almost)
reflects the desired state of the new release. At least all features that are targeted for the
release-to-be-built must be merged in to develop at this point in time. All features targeted
at future releases may not—they must wait until after the release branch is branched off.
It is exactly at the start of a release branch that the upcoming release gets assigned a
version number—not any earlier. Up until that moment, the develop branch reflected
changes for the “next release”, but it is unclear whether that “next release” will eventually
become 0.3 or 1.0, until the release branch is started. That decision is made on the start of
the release branch and is carried out by the project’s rules on version number format and
protocol that is followed as a general practice.

Creating a Release branches:


Once develop has acquired enough features for a release (or a predetermined release date is
approaching), you fork a release branch off of develop. Creating this branch starts the next
release cycle, so no new features can be added after this point—only bug fixes,
documentation generation, and other release-oriented tasks should go in this branch. Once it's
ready to ship, the release branch gets merged into main and tagged with a version number. In
addition, it should be merged back into develop, which may have progressed since the release
was initiated.

Using a dedicated branch to prepare releases makes it possible for one team to polish the
current release while another team continues working on features for the next release. It also
creates well-defined phases of development (e.g., it's easy to say, “This sprint we're getting
ready for version 4.0,” and to actually see it in the structure of the git repository).

Making release branches is another straightforward branching operation.


Like feature branches, release branches are based on the develop branch. A
new release branch can be created using the following methods.

Without the git-flow extensions:


git checkout develop
git checkout -b release/0.1.0
When using the git-flow extensions:

$ git flow release start 0.1.0
Switched to a new branch 'release/0.1.0'
Once the release is ready to ship, it will get merged it into main and develop, then
the release branch will be deleted. It’s important to merge back into develop because
critical updates may have been added to the release branch and they need to be accessible
to new features. If your organization stresses code review, this would be an ideal place for a
pull request.

To finish a release branch, use the following methods:

Without the git-flow extensions:

git checkout main
git merge release/0.1.0

Or with the git-flow extension:

git flow release finish '0.1.0'

Hotfix branches: Creating the hotfix branches as in the diagram below and descriptions.

Maintenance or “hotfix” branches are used to quickly patch production


releases. Hotfix branches are a lot like release branches and feature branches except they're
based on main instead of develop. This is the only branch that should fork directly off
of main. As soon as the fix is complete, it should be merged into both main and develop (or
the current release branch), and main should be tagged with an updated version number.

Having a dedicated line of development for bug fixes lets your team address issues without
interrupting the rest of the workflow or waiting for the next release cycle. You can think of
maintenance branches as ad hoc release branches that work directly with main.
A hotfix branch can be created using the following methods:

Without the git-flow extensions:

git checkout main
git checkout -b hotfix_branch

When using the git-flow extensions: 

$ git flow hotfix start hotfix_branch

Similar to finishing a release branch, a hotfix branch gets merged into both main and develop.

git checkout main
git merge hotfix_branch
git checkout develop
git merge hotfix_branch
git branch -D hotfix_branch
$ git flow hotfix finish hotfix_branch

Example: A complete example demonstrating a Feature Branch Flow is as follows.


Assuming we have a repo setup with a main branch.

git checkout main
git checkout -b develop
git checkout -b feature_branch
# work happens on feature branch
git checkout develop
git merge feature_branch
git checkout main
git merge develop
git branch -d feature_branch
In addition to the feature and release flow, a hotfix example is as follows:
git checkout main
git checkout -b hotfix_branch
# work is done commits are added to the hotfix_branch
git checkout develop
git merge hotfix_branch
git checkout main
git merge hotfix_branch

Key Considerations for Code Repository in Git:

The overall flow of Git Branching is:


 A develop branch is created from main
 A release branch is created from develop
 Feature branches are created from develop
 When a feature is complete it is merged into the develop branch
 When the release branch is done it is merged into develop and main
 If an issue in main is detected a hotfix branch is created from main
 Once the hotfix is complete it is merged to both develop and main

Forking of Workflow:

The Forking Workflow is fundamentally different than other popular Git workflows. Instead
of using a single server-side repository to act as the “central” codebase, it gives every
developer their own server-side repository. This means that each contributor has not one,
but two Git repositories: a private local one and a public server-side one. The Forking
Workflow is most often seen in public open source projects.

The main advantage of the Forking Workflow is that contributions can be integrated without
the need for everybody to push to a single central repository. Developers push to their own
server-side repositories, and only the project maintainer can push to the official repository.
This allows the maintainer to accept commits from any developer without giving them write
access to the official codebase.

The Forking Workflow typically follows a branching model based on the Gitflow Workflow.
This means that complete feature branches will be purposed for merge into the original
project maintainer's repository. The result is a distributed workflow that provides a flexible
way for large, organic teams (including untrusted third-parties) to collaborate securely. This
also makes it an ideal workflow for open source projects.
 
How it works:
As in the other Git workflows, the Forking Workflow begins with an official public repository
stored on a server. But when a new developer wants to start working on the project, they
do not directly clone the official repository.
Instead, they fork the official repository to create a copy of it on the server. This new copy
serves as their personal public repository—no other developers are allowed to push to it,
but they can pull changes from it (we’ll see why this is important in a moment). After they
have created their server-side copy, the developer performs a git clone to get a copy of it
onto their local machine. This serves as their private development environment, just like in
the other workflows.
When they're ready to publish a local commit, they push the commit to their own public
repository—not the official one. Then, they file a pull request with the main repository,
which lets the project maintainer know that an update is ready to be integrated. The pull
request also serves as a convenient discussion thread if there are issues with the
contributed code. The following is a step-by-step example of this workflow.
 
 A developer 'forks' an 'official' server-side repository. This creates their own server-
side copy.
 The new server-side copy is cloned to their local system.
 A Git remote path for the 'official' repository is added to the local clone.
 A new local feature branch is created.
 The developer makes changes on the new branch.
 New commits are created for the changes.
 The branch gets pushed to the developer's own server-side copy.
 The developer opens a pull request from the new branch to the 'official' repository.
 The pull request gets approved for merge and is merged into the original server-side
repository
 
To integrate the feature into the official codebase, the maintainer pulls the contributor’s
changes into their local repository, checks to make sure it doesn’t break the project, merges
it into their local main branch, then pushes the main branch to the official repository on the
server. The contribution is now part of the project, and other developers should pull from
the official repository to synchronize their local repositories.
It’s important to understand that the notion of an “official” repository in the Forking
Workflow is merely a convention. In fact, the only thing that makes the official repository so
official is that it’s the public repository of the project maintainer.

Forking vs cloning:
It's important to note that "forked" repositories and "forking" are not special operations.
Forked repositories are created using the standard git clone command. Forked repositories
are generally "server-side clones" and usually managed and hosted by a 3rd party Git
service. There is no unique Git command to create forked repositories. A clone operation is
essentially a copy of a repository and its history. 

Branching in the Forking Workflow:


All of these personal public repositories are really just a convenient way to share branches
with other developers. Everybody should still be using branches to isolate individual
features, just like in the Feature Branch Workflow and the Gitflow Workflow. The only
difference is how those branches get shared. In the Forking Workflow, they are pulled into
another developer’s local repository, while in the Feature Branch and Gitflow Workflows
they are pushed to the official repository.
Fork a repository:
All new developers to a Forking Workflow project need to fork the official repository. As
previously stated, forking is just a standard git clone operation. It’s possible to do this by
SSH’ing into the server and running git clone to copy it to another location on the server.
Popular Git hosting services, offer repo forking features that automate this step.

Clone your fork:


Next each developer needs to clone their own public forked repository. They can do this
with the familiar git clone command.
Assuming the use of github to host these repositories, developers on a project should have
their account and they should clone their forked copy of the repository with:

git clone https://user@github.org/user/repo.git

Adding a remote:
Whereas other Git workflows use a single origin remote that points to the central
repository, the Forking Workflow requires two remotes—one for the official repository, and
one for the developer’s personal server-side repository. While you can call these remotes
anything you want, a common convention is to use origin as the remote for your forked
repository (this will be created automatically when you run git clone) and upstream for the
official repository.

git remote add upstream https://github.org/maintainer/repo

You’ll need to create the upstream remote yourself using the above command. This will let
you easily keep your local repository up-to-date as the official project progresses. Note that
if your upstream repository has authentication enabled (i.e., it's not open source), you'll
need to supply a username, like so:

git remote add upstream https://user@github.org/maintainer/repo.git


This requires users to supply a valid password before cloning or pulling from the official
codebase.

Working in a branch: making & pushing changes:


In the developer's local copy of the forked repository they can edit code, commit changes,
and create branches just like in other Git workflows:

git checkout -b some-feature # Edit some code git commit -a -m "Add first or initial draft of
given feature"
All of their changes will be entirely private until they push it to their public repository. And,
if the official project has moved forward, they can access new commits with git pull:

git pull upstream main


Since developers should be working in a dedicated feature branch, this should generally
result in a fast-forward merge.
Making a Pull Request:
Once a developer is ready to share their new feature, they need to do two things. First, they
have to make their contribution accessible to other developers by pushing it to their public
repository. Their origin remote should already be set up, so all they should have to do is the
following:
git push origin feature-branch
This diverges from the other workflows in that the origin remote points to the developer’s
personal server-side repository, not the main codebase.
Second, they need to notify the project maintainer that they want to merge their feature
into the official codebase. Github provides a “pull request” button that leads to a form
asking you to specify which branch you want to merge into the official repository. Typically,
you’ll want to integrate your feature branch into the upstream remote’s main branch.

Summary
To recap, the Forking Workflow is commonly used in public open-source projects. Forking is
a git clone operation executed on a server copy of a projects repo. A Forking Workflow is
often used in conjunction with a Git hosting service. A high-level example of a Forking
Workflow is:

 You want to contribute to an open source library hosted at github.org/userA/open-


project
 Using git you create a fork of the repo to github.org/YourName/open-project
 On your local system you execute git clone on https://github.org/YourName/open-
project to get a local copy of the repo
 You create a new feature branch in your local repo
 Work is done to complete the new feature and git commit is executed to save the
changes
 You then push the new feature branch to your remote forked repo

The Forking Workflow helps a maintainer of a project open up the repository to


contributions from any developer without having to manually manage authorization settings
for each individual contributor. This gives the maintainer more of a "pull" style workflow.
Most commonly used in open-source projects, the Forking Workflow can also be applied to
private business workflows to give more authoritative control over what is merged into a
release. This can be useful in teams that have Deploy Managers or strict release cycles.

References –

https://docs.github.com/en/get-started/quickstart/github-flow

https://docs.github.com/en/get-started/quickstart/set-up-git

You might also like