Read Anthropic’s case study about Graphite Reviewer

Understanding the "Git Flow" workflow

Greg Foster
Greg Foster
Graphite software engineer


Note

This guide explains this concept in vanilla Git. For Graphite documentation, see our CLI docs.


The Git Flow workflow, introduced by Vincent Driessen in 2010, is a branching and release management strategy designed to boost the development process's efficiency, especially in versioned or continuously developed projects. This workflow has become widely popular among software teams for managing complexities of the development lifecycle. In this guide, we will delve into the Git Flow workflow, exploring its core branches, usage scenarios, and commands through a detailed example, helping you grasp its intricacies and understand why and how it can be beneficial for your projects.

The Git Flow model is structured around two main branches with an infinite lifetime:

  1. Main (formerly master): This branch contains production-ready code at all times.
  2. Develop: This is the main integration branch where features are integrated, and it serves as a basis for the next releases.

Aside from these main branches, Git Flow incorporates several types of support branches to aid in the continuous development process, including:

  • Feature branches: For developing new features.
  • Release branches: For preparing a new production release.
  • Hotfix branches: For making critical fixes to the production version.

This model not only segregates the development efforts into distinct branches but also dictates specific interactions among these branches, ensuring a structured and error-minimizing workflow:

The main branch holds the code that is currently in production. Every change made to this branch is considered stable and deployable. As such, it acts as a snapshot of your software's current live state. This branch only receives code from the Release and Hotfix branches, ensuring that all changes are vetted and tested before they affect your live environment.

The develop branch serves as the primary branch for all development work. This is where all feature branches are merged after completion. It acts as an integration point for new developments and, once stable, feeds into the Release branch for the next production rollout. The Develop branch represents the cutting edge of your project and is where continuous integration testing can be most beneficial.

Feature branches are temporary and are created from the Develop branch for the purpose of developing new features or enhancements without affecting the stability of the Develop branch. Each feature branch is focused on a specific task and should be relatively short-lived. Once the feature is completed and tested, it is merged back into the Develop branch and the feature branch is deleted. This keeps the repository clean and manageable.

Release branches are branched off from the Develop branch when a certain set of features is ready to be released. This branch is where final adjustments (like bug fixes, documentation, and other release-oriented tasks) are made, and once everything is tested and finalized, it is merged into the Main branch and tagged with a version number. After merging into Main, it is also merged back into the Develop branch to ensure that any changes made in the Release branch are not lost, which might include bug fixes and other important updates that need to be available for future releases.

Hotfix branches are used for making quick critical fixes to the live production environment. These are branched directly from Main because they aim to address immediate issues affecting the current live system. After the fix is verified, the Hotfix branch is merged back into both the Main and Develop branches. This is crucial to ensure that the same problem does not reoccur in future releases, and it maintains consistency across the codebase.

By adhering to this structured branching strategy, teams can achieve a high level of control and organization over their development processes. The use of different branches for different purposes (development, new features, releases, and hotfixes) reduces the risk of introducing errors into production and makes it easier to track changes and manage versions. The Git Flow model also facilitates continuous delivery by allowing teams to develop, test, and release software at a more rapid pace and with greater reliability.

This model's clarity and separation of concerns make it ideal for projects requiring frequent updates and maintenance, providing a clear path from development to deployment. It ensures that all development efforts are systematically integrated, tested, and released, which enhances the overall efficiency and quality of the software development process.

To start with the Git Flow model, you first need to configure your branch structure properly:

Initialize your Git repository:

Terminal
git init

Add the develop branch: While the main branch is automatically created for you upon running git init we also have to create a "develop" branch which we'll use as the primary branch for all of our development work.

Terminal
git checkout -b develop main
git push -u origin develop

This setup defines develop as the branch where all the integration happens and main as the branch reflecting the production-ready state.

Feature branches are used to develop new enhancements or features independently. They branch from and merge back into the develop branch.The feature branch workflow is particularly beneficial in collaborative environments where multiple developers are working on various aspects of a project simultaneously.

By isolating each feature into its own branch, it ensures that the develop branch remains stable, reducing the risk of introducing bugs into the main line of development. Each feature branch should be dedicated to a specific piece of functionality or improvement and is independent of other feature branches, which allows for targeted testing and code review. This isolation simplifies both understanding and troubleshooting the feature during development. Once a feature is completed, tested, and code-reviewed, it can be merged back into the develop branch, making it part of the next scheduled release cycle.

Creating a feature branch:

Terminal
git checkout -b feature/<feature_name> develop

Integrating a completed feature:

Terminal
git checkout develop
git merge --no-ff feature/<feature_name>
git branch -d feature/<feature_name>
git push origin develop

The --no-ff option creates a merge commit even if a fast-forward merge is possible, preserving the history of the feature branch as a separate entity. This makes it easier to understand the context of changes and facilitates both tracking of specific feature developments and facilitates potential reversions of entire features if necessary.

Release branches help prepare a new production release. They allow for minor bug fixes and preparation for the release like updating metadata and version numbers.

Creating a release branch:

Terminal
git checkout -b release/<version> develop

Completing the release branch:

After final tweaks and updates:

Terminal
git checkout main
git merge --no-ff release/<version>
git tag -a <version>
git checkout develop
git merge --no-ff release/<version>
git branch -d release/<version>
git push origin main --tags
git push origin develop

Tagging the release in the main branch helps in tracking versions and can facilitate deployment processes.

Hotfix branches are used to act immediately upon an undesired state of a live production version. They allow for quick fixes to production without disrupting the ongoing work on development.

Creating a hotfix branch:

Terminal
git checkout -b hotfix/<version> main

Finishing a hotfix branch:

After the fix is applied:

Terminal
git checkout main
git merge --no-ff hotfix/<version>
git tag -a <version>
git checkout develop
git merge --no-ff hotfix/<version>
git branch -d hotfix/<version>
git push origin main --tags
git push origin develop

For further reading on the GitFlow model see Vincent Driessen's original proposal.

Git inspired
Graphite's CLI and VS Code extension make working with Git effortless.
Learn more

Graphite
Git stacked on GitHub

Stacked pull requests are easier to read, easier to write, and easier to manage.
Teams that stack ship better software, faster.

Or install our CLI.
Product Screenshot 1
Product Screenshot 2