Git Flow Workflow: The Best Practice Guide
In modern software development, version control is not just a backup tool for code, but the very cornerstone of team collaboration. Among various Git branching models, Git Flow, with its rigorous structure and clear release rhythm, has become the preferred choice for many large-scale projects and mid-sized teams.
This article will provide an in-depth, illustrated analysis of the core concepts and best practices of Git Flow, helping your team establish an efficient and reliable code management standard.
1. What is Git Flow?
Git Flow is a Git-based branching model proposed by Vincent Driessen in 2010. By defining clear branch roles and strict merge rules, it is specifically designed to manage complex software release cycles.
If your project has a clear release cycle (such as versioned releases like V1.0, V2.0), or needs to maintain older versions while developing new ones, Git Flow will be highly suitable for you.
2. Core Branching Model & Diagram
The core of Git Flow lies in its five types of branches. Let’s build an intuitive understanding through a global relationship diagram:
gitGraph commit id: "Initial Commit" branch develop checkout develop commit id: "Project Setup" branch feature/login checkout feature/login commit id: "Add login UI" commit id: "Add auth logic" checkout develop merge feature/login branch release/v1.0.0 checkout release/v1.0.0 commit id: "Bump version to v1.0.0" commit id: "Fix minor bug" checkout main merge release/v1.0.0 tag: "v1.0.0" checkout develop merge release/v1.0.0 checkout main branch hotfix/v1.0.1 checkout hotfix/v1.0.1 commit id: "Fix critical production bug" checkout main merge hotfix/v1.0.1 tag: "v1.0.1" checkout develop merge hotfix/v1.0.1
1. The Main Branches
In Git Flow, two branches have a permanent lifespan:
main (or master)
Always in a production-ready state. Only thoroughly tested code can be merged into this branch. Every merge to main is typically tagged with a version number.
develop
The integration branch for daily development. It contains all the latest feature code ready for the next release. When the code on develop stabilizes and is ready for release, it is merged back into main.
2. Supporting Branches
Supporting branches should be deleted immediately after completing their specific tasks to avoid branch pollution:
feature/* (Feature Branches)
| Attribute | Description |
|---|---|
| Source | develop |
| Destination | develop |
Used to develop new features. Each new feature should be developed on a separate branch. Once development is complete, it is merged back into develop via a Pull Request (PR) and immediately deleted.
release/* (Release Branches)
| Attribute | Description |
|---|---|
| Source | develop |
| Destination | main and develop |
When develop has accumulated enough new features and is ready for a version release, a release branch is branched off (e.g., release/v1.2). Only bug fixes, documentation updates, and version bumps are allowed on this branch; developing new features is strictly prohibited. Once testing passes, it is merged into main and tagged for release, as well as merged back into develop to ensure fixes are synchronized. Finally, the branch is deleted.
hotfix/* (Hotfix Branches)
| Attribute | Description |
|---|---|
| Source | main |
| Destination | main and develop |
When an urgent bug occurs in the live production environment (main branch) and needs immediate fixing, this branch is cut from main. Once fixed, it is immediately merged back into main for an emergency release (tagged with a new version) and also merged back into develop to prevent the bug from regressing in the next release. Finally, the branch is deleted.
3. Core Rules of Git Flow Best Practices
Understanding the model is only the first step; implementation is key. Here are the golden rules for teams practicing Git Flow:
🚨 1. No Direct Commits
Strictly Prohibited
Never run git push directly to main and develop branches.
All changes to these two core branches must be made through Merge Requests / Pull Requests (PRs). Set up Branch Protection rules on code hosting platforms (like GitLab, GitHub) to enforce this.
🔍 2. Mandatory Code Review
When a feature branch is merged into develop, it must be reviewed by at least one other team member. This is not only for catching bugs, but is also the best opportunity for knowledge sharing and unifying code style.
🏷️ 3. Standardized Naming & Commit Messages
Branch Naming Convention: Use prefixes to clarify the branch type.
feature/JIRA-123-add-payment-gatewayrelease/v2.1.0hotfix/fix-login-crashCommit Message Convention: Conventional Commits are recommended.
feat: add user login functionalityfix: correct payment calculation on order pagedocs: update API endpoints documentationchore: upgrade dependency versions♻️ 4. Keep Branch Lifespans Short
The lifespan of a feature branch should not be too long (ideally no more than a week). If a feature is large, break it down into multiple small, independently deliverable features. A feature branch left unmerged for too long leads to painful conflict resolution (Merge Hell).
♻️ 5. Sync Remote Code Frequently
While developing on a feature branch, get into the habit of running the following commands daily to detect and resolve conflicts early, rather than letting them pile up until you open a PR:
# Option 1: merge (keeps merge commit history)git pull origin develop
# Option 2: rebase (maintains linear history, recommended)git fetch origingit rebase origin/develop🎯 6. Hotfixes and Releases Must Be Merged “Both Ways”
This is the most common mistake made by beginners: fixing a production bug (merged to main) but forgetting to merge it back into develop, causing the old bug to reappear in the next release.
⚠️ Important Reminder
Any code that enters main, whether a release or a hotfix, must be synchronized back into develop.
4. Common Workflow Scenarios Demonstration
Scenario A: Developing a New Feature (Feature)
# 1. Branch off from developgit checkout -b feature/user-profile develop
# 2. Develop and commitgit commit -m "feat: add user profile page"
# 3. Push and create a PR/MR requesting to merge into developgit push origin feature/user-profile
# 4. Once reviewed and merged, delete the branchgit branch -d feature/user-profilegit push origin --delete feature/user-profileScenario B: Preparing a New Version Release (Release)
# 1. Once develop features are ready, create release branch from developgit checkout -b release/v1.1.0 develop
# 2. Only perform version bumps, bug fixes, and documentation updatesgit commit -m "chore: bump version to v1.1.0"git commit -m "fix: resolve edge case in payment flow"
# 3. Merge to main and Tag itgit checkout maingit merge release/v1.1.0git tag -a v1.1.0 -m "Release v1.1.0"git push origin main --tags
# 4. Sync back to developgit checkout developgit merge release/v1.1.0
# 5. Delete release branchgit branch -d release/v1.1.0git push origin --delete release/v1.1.0Scenario C: Urgently Fixing a Live Bug (Hotfix)
# 1. Branch off from maingit checkout -b hotfix/v1.1.1 main
# 2. Fix bug and testgit commit -m "fix: resolve memory leak on login"
# 3. Merge to main and Tag itgit checkout maingit merge hotfix/v1.1.1git tag -a v1.1.1 -m "Hotfix v1.1.1"git push origin main --tags
# 4. Sync back to develop (Critical step, do not skip!)git checkout developgit merge hotfix/v1.1.1
# 5. Delete hotfix branchgit branch -d hotfix/v1.1.1git push origin --delete hotfix/v1.1.15. Summary & Selection Advice
Advantages
- Strict branch definitions with distinct responsibilities for development, testing, and release stages.
- Highly suitable for supporting multiple versions concurrently and products with fixed release cycles.
- Easy to trace historical versions, providing high security for the production environment.
Limitations (When Not to Use)
For SaaS projects with high CI/CD requirements that need to release multiple times a day, Git Flow is overly heavy. Consider the following alternatives:
| Model | Applicable Scenarios | Core Philosophy |
|---|---|---|
| GitHub Flow | Small teams, continuous deployment | Only main + feature branches, PR is release |
| Trunk Based Development | High-frequency releases, mature DevOps teams | Everyone commits directly to trunk, relies on Feature Flags |
| Git Flow | Versioned products, multi-version maintenance | Strict branch roles and release pipelines |
One-Sentence Summary
Git Flow is like a precision assembly line—the process is strict and even slightly tedious, but as long as everyone follows the rules, it guarantees that code arrives smoothly and on time in the production environment.

