Branching Models
Last updated on 2025-03-12 | Edit this page
Overview
Questions
- Which branching model is best for me?
Objectives
- Describe the Feature Branch and Forking models.
In the git-novice lesson you learnt how to develop features on a
branch and use a pull-request to merge the changes back into the
main
branch. You were unknowingly using a Git branching
model called feature branch workflow.
As a reminder, we develop on branches to ensure that our development
code doesn’t affect the production code on the main
branch.
Branches also allow your team to develop features in parallel.
A branching model (sometimes also called strategies or workflows) is the model your team adopts when writing, merging and deploying code when using a version control system. It is a set of rules that you must follow which outline how your team and collaborators interact with a shared codebase.
Having a clear model helps avoid merge conflicts, more on that later, and clearly sets out to new collaborators how they can contribute to your repository.
In this and the following episodes, we will outline some of the branching models that teams use in order to organize their work. We will look at their pros and cons and help decide which model you should choose based on your teams needs.
A branching model aims to:
- Enhance productivity by ensuring proper coordination among developers
- Enable parallel development
- Help organize a series of planned, structured releases
- Map a clear path when making changes from development through to production
- Maintain a bug-free code where developers can quickly fix issues and get these changes back to production without disrupting the development workflow
Git Branching Models
Some version control systems are more geared towards certain branching models. When using git you have a wide range of models to pick from. This means the first rule when collaborating using git is: “Talk about your branching model.”
A repository’s CONTRIBUTING
file may include details of
their branching model. This information might also be in a repository’s
README
file. If in doubt ask! You can also look at how
other people appear to be contributing to the repository.
Below are a few models:
Feature Branch
In this model every small change or “feature” gets its own branch
where the developers make changes. Once the feature is done, they submit
a pull request and merge it into the main
branch after
review. Feature branches should be relatively short-lived. Each
collaborator must have write level, or higher,
permissions on the repository. There are 2 repositories for each person
to be mindful of, local and
origin.
Pros
- Developers create each feature away from
main
so you don’t affect production code. - Developers can create many features in parallel feature branches.
- It’s a simple model that’s easy for those new to git and your project.
- Easy to set up with continuous integration testing and deployment.
Cons
- If you don’t regularly merge changes to
main
into your feature branch it can become outdated, leading to merge conflicts. - You may struggle if you need to maintain multiple production versions simultaneously in the same repository.
The Feature Branch model is sometimes called GitHub Flow. Note that all branches and commits exist within the single GitHub, origin repository. They are visible to anyone who has read access to the repository. Any contributor can write to any branch that is not explicitly protected.
---
title: Feature Branch Model
---
flowchart TD
accDescr {A flowchart showing the feature branch model.
Here developers work on their local copies of the
GitHub repository. All developers have write access
or higher. Developers work on feature branches,
and push these branches to the origin repository.}
subgraph subGraph0["Remote Server (GitHub)"]
r1[("MetOffice/git-training-demo Origin Repository")]
end
subgraph subGraph1["<div style=margin-top:>Computer 3</div>"]
r2[("Local Repository")]
end
subgraph subGraph2["<div style=margin-top:>Computer 2</div>"]
r3[(" Local Repository")]
end
subgraph subGraph3["<div style=margin-top:>Computer 1</div>"]
r4[("Local Repository")]
end
r1 -- fetch/pull --> r2 & r3 & r4
r2 -. push .-> r1
r3 -. push .-> r1
r4 -. push .-> r1
style subGraph1 fill:#A9640A
style subGraph2 fill:#A9640A
style subGraph3 fill:#A9640A
---
config:
gitGraph:
showCommitLabel: false
---
gitGraph
accDescr {A git graph showing four branches including the default
main branch.
Each circle is a commit.
A circle with an outline but no fill colour is a merge commit
where one branch has been merged into another.
The two feature branches and the bug_fix branch
all branch off of main at the same commit.
The bug_fix and small_feature branches
are merged back into main after
being developed on their branches.
The large_feature branch merges in the
changes to main to fix any conflicts
before the feature is ready to be merged
back into the main branch via a pull request.}
commit
branch bug_fix
checkout main
branch small_feature
checkout main
branch large_feature
checkout bug_fix
commit
checkout large_feature
commit
checkout main
merge bug_fix
checkout small_feature
commit
checkout large_feature
commit
checkout small_feature
commit
checkout main
merge small_feature
checkout large_feature
commit
merge main
checkout main
merge large_feature
Forking
In this model you make a fork (copy) of the whole repository you want to contribute to on GitHub in your personal space. You develop your changes using this fork. When a change is ready you open a pull request to contribute the changes back to the original repository. There are 3 repositories for each person to be mindful of, local, origin (your fork), and upstream (the original repository).
Pros
- Removes the need to give all collaborators write level or higher permissions on your repository. Anyone with read access to a repository can contribute.
- Only project maintainers can approve new code.
- You can use any other model within your main repository and forks to develop changes.
All branches and commits exist within the collaborators fork, not the upstream repository. They are harder to find for anyone who has read access to the upstream repository.
Collaborators can use their fork to test more complex changes. For example testing github actions within a dummy-PR.
---
title: Forking + Feature Branch
---
flowchart TB
accDescr {A flowchart showing the use of forks
and the feature branch model.
Here developers work on their forks (GitHub copies, labelled origin) of the
main GitHub repository (upstream).
Developers work on feature branches in their fork,
and push these branches to the origin repository.
Pull requests are used to contribute changes from
the origin to the upstream repository.
Only one developers fork and local repository
are shown in this diagram.}
subgraph top["Remote Server (GitHub)"]
direction LR
r1[("MetOffice/git-training-demo Upstream Repository")]
r2[("username/git-training-demo Origin Repository")]
r2 -. Pull Request .-> r1
end
subgraph bottom["Computer"]
r3[("Local Repository")]
end
r1 -- fetch/pull --> r3
r3 -- push --> r2
r2 -- fetch/pull --> r3
style bottom fill:#A9640A
Git Flow
In this model the main development occurs in a develop
branch. Feature branches are created from this develop
branch. When the develop
branch is ready for a release, you
create a release
branch which is then tested and merged
onto the develop
and main
branches.
Cons
- Steeper learning curve, novices may require more help.
gitGraph
accDescr {A git graph showing the GitFlow model.}
commit tag:"0.1"
branch hotfix
checkout main
branch release
branch develop
checkout hotfix
commit
checkout develop
commit
branch small_feature
checkout develop
merge hotfix
branch large_feature
checkout small_feature
commit
checkout large_feature
commit
commit
checkout main
merge hotfix tag:"0.2"
checkout small_feature
commit
checkout develop
merge small_feature
checkout release
merge develop
checkout large_feature
commit
checkout release
commit
commit
checkout main
merge release tag:"1.0"
checkout develop
merge release
Recommendations
For repositories where collaborators are a small and trusted group the Feature Branch model is normally sufficient.
A Forking model may be preferable if:
- There are more collaborators, because the number of branches may become unwieldy.
- There are external collaborators whose contribution is valued, but the repository owners need to retain control of the original. For this reason most open source projects use a Forking Model.
These working pattern are conventions not rules. It is easy to switch from one working pattern to the other. Or even to use the feature branch pattern for trusted colleagues and the forking pattern for outside contributors.
This wasn’t an exhaustive list of branching models! You can find more information using the links below:
- From Novice to Pro: Understanding Git Branching Strategies, GitProtect
- What is a Git workflow?, GitLab
Terminology
Use the glossary to explain the differences between the following:
- A branch
- A remote
- A fork
Learners are often confused by the difference between branches, remotes, and forks.
- Branches are pointers to commits in a repository. A repository will have multiple branches where developers can work on features in parallel.
- Remotes are links to other repositories. These remotes usually link to repositories on cloud platforms such as GitHub. A repository typically has one or more remotes, with the first called origin.
- A fork is a copy of a repository created on GitHub. When linking your local repository your fork becomes the origin remote. The original repository you forked from becomes the upstream remote.
Key Points
- A clearly communicated branching model helps developers.
- For small projects use the Feature Branch flow.
- For larger projects or those with external collaborators use forks with feature branches.