Git Flow Branching Strategy
Git Flow
Git Flow uses multiple long-lived branches, including main
, develop
, release
, and hotfix
, in addition to short-lived feature branches. This strategy provides a structured process for managing different types of changes, making it ideal for large teams and complex projects.
Advantages:
Organized and structured process
Clear separation between production and development code
Scales well for large teams and complex projects
Disadvantages:
Can be overly complex for smaller teams or projects
Frequent merging and branch management can be time-consuming
Explain the Git Flow Branching Strategy
"In Git Flow, we manage our development using several long-lived and short-lived branches:
The
main
branch (ormaster
) holds production-ready code and is always stable.The
develop
branch is used for ongoing development and serves as the integration branch for features before they go live.Feature branches are created for new features or tasks and merged into
develop
once they are complete and tested.For releases, we use release branches to prepare the code for production.
In case of urgent fixes in production, we create hotfix branches off the
main
branch to resolve issues quickly."
(Note: Please *ignore the typo 'develop').
💻 Key Topics Covered:
How Git Flow branches work (main, develop, feature, release, hotfix)
Automating deployment using CI/CD Pipelines
Merging best practices
Use cases and benefits for large teams
Summary of Steps in Git Flow Process:
Create the
develop
branch.Create a feature branch from
develop
for each new feature.Develop and commit the feature in the feature branch.
Open a pull request and trigger the CI pipeline for testing and review.
Merge the feature branch back into
develop
.Create a release branch for finalizing the release.
Merge the release branch into
main
for production deployment.Tag the release for versioning.
Merge the release branch back into
develop
to sync changes.Handle hotfixes by creating a hotfix branch from
main
and merging it back into bothmain
anddevelop
.
How Git Flow branches work (main, develop, feature, release, hotfix):
Step 1: Create and Switch to the develop
Branch
Since develop
acts as the main integration branch for ongoing development, the first step is to create it if it doesn’t already exist:
# Create and switch to the develop branch
git checkout -b develop
Step 2: Create a Feature Branch from develop
Each new feature or task should be developed in its own branch, created from the develop
branch. This isolates new development until it’s ready to be merged back into develop
.
# Create a feature branch from develop
git checkout -b feature-branch develop
Step 3: Develop the Feature
Now, make changes to your code in the feature branch and commit them. This may include writing code, adding tests, and making necessary changes.
# Make changes to the feature and commit them
git add .
git commit -m "Implement new feature"
Step 4: Open a Pull Request
Push your feature branch to the remote repository and open a pull request (PR) to merge it back into develop
.
# Push the feature branch to the remote repository
git push origin feature-branch
After pushing, open a pull request on GitHub (or your Git platform) to merge the feature branch into develop
. This triggers a Jenkins pipeline that will:
CI/CD Pipeline for Feature Branches
Use Case: Automatically run tests on feature branches before merging into
develop
.Automation Steps:
Set up a pipeline triggered by pull requests (PRs) to ensure that the code passes all tests before it is merged into
develop
.This pipeline can:
Build the application.
Run unit and integration tests.
Perform code quality checks using tools like SonarQube.
Conduct security scans using tools like Trivy or Aqua Security.
Benefits:
- Ensures that only clean, tested code is merged into
develop
.
Feature Branche Pipeline Example:
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git branch: 'feature/*', url: 'https://github.com/your-repo-url.git'
}
}
stage('Build') {
steps {
sh 'mvn clean package' // Example build command for Java app
}
}
stage('Unit Tests') {
steps {
sh 'mvn test' // Run unit tests
}
}
stage('Code Quality Check') {
steps {
sh 'mvn sonar:sonar' // Code quality analysis using SonarQube
}
}
stage('Security Scan') {
steps {
sh 'trivy image your-app-image:tag' // Security scan for Docker image
}
}
}
post {
success {
echo 'Feature branch build and tests passed!'
}
failure {
echo 'Build or tests failed, please review.'
}
}
}
Step 5: Merge Feature Branch Back into develop
Once the Jenkins pipeline passes, and the pull request has been reviewed and approved, the feature branch can be merged back into develop
.
# Switch to the develop branch
git checkout develop
# Merge the feature branch into develop
git merge feature-branch
Once merged, Jenkins triggers the pipeline for the develop
branch:
CI/CD Pipeline for develop
Branch
Use Case: Deploy code from the develop
branch to a staging environment for integration testing.
Automation Steps:
Once a feature branch is merged into
develop
, trigger an automated pipeline to:Build and test the code.
Deploy the application to a staging or QA environment for further testing.
Run end-to-end tests to ensure the full functionality works as expected.
Benefits:
- Ensures that the
develop
branch remains stable and ready for integration.
Develop Branch Pipeline Example:
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git branch: 'develop', url: 'https://github.com/your-repo-url.git'
}
}
stage('Build') {
steps {
sh 'mvn clean package'
}
}
stage('Integration Tests') {
steps {
sh 'mvn verify' // Run integration tests to ensure compatibility
}
}
stage('Deploy to Staging') {
steps {
sh './deploy-to-staging.sh' // Custom script to deploy to staging environment
}
}
stage('End-to-End Tests') {
steps {
sh './run-e2e-tests.sh' // End-to-end tests in staging
}
}
}
post {
success {
echo 'Code successfully tested in staging environment.'
}
failure {
echo 'Issues found in integration or e2e tests.'
}
}
}
Step 6: Create a Release Branch
When the develop
branch is stable and ready for release, create a release branch. This branch is used to prepare the code for production, fix any final bugs, and ensure documentation is updated.
# Create a release branch from develop
git checkout -b release/v1.0 develop
On creating the release branch, Jenkins will trigger another pipeline to perform:
CI/CD Pipeline for Release Branches
Use Case: Prepare the code for production by running final tests and deployment scripts.
Automation Steps:
When a release branch is created, trigger the following in your CI/CD pipeline:
Run all final tests.
Build the application with production-ready configurations.
Optionally, update documentation and run security audits.
Deploy the code to a staging environment for final validation before it’s merged into
main
.
Benefits:
- Ensures that the release branch is fully ready for production with minimal risk.
Release Branch Pipeline Example:
pipeline {
agent any
// Trigger the pipeline when working with release branches
triggers {
pollSCM('* * * * *') // Adjust polling as per need (e.g., using Git hooks instead)
}
environment {
SONARQUBE_URL = 'http://sonarqube-url'
TRIVY_IMAGE = 'your-app-image:latest'
DOCS_GENERATOR_SCRIPT = './generate-docs.sh' // Adjust the script path as needed
}
stages {
stage('Checkout Code') {
steps {
// Only run for release branches
script {
if (env.BRANCH_NAME.startsWith("release/")) {
echo "Processing release branch: ${env.BRANCH_NAME}"
} else {
error("This pipeline should only run on release branches.")
}
}
git branch: env.BRANCH_NAME, url: 'https://github.com/your-repo-url.git'
}
}
stage('Build') {
steps {
echo 'Building the release...'
sh 'mvn clean package' // Example for Java app
}
}
stage('Final Tests') {
steps {
echo 'Running final tests...'
sh 'mvn test'
sh 'mvn verify' // Integration and other tests
}
}
stage('Code Quality Check') {
steps {
echo 'Running code quality check...'
withSonarQubeEnv('SonarQube') { // Use your SonarQube setup
sh 'mvn sonar:sonar'
}
}
}
stage('Security Scan') {
steps {
echo 'Running security scan using Trivy...'
sh "trivy image ${TRIVY_IMAGE}"
}
}
stage('Documentation Preparation') {
steps {
echo 'Generating documentation...'
sh "${DOCS_GENERATOR_SCRIPT}" // Custom script to generate documentation
}
}
stage('Archive Artifacts') {
steps {
echo 'Archiving build artifacts...'
archiveArtifacts artifacts: '**/target/*.jar', allowEmptyArchive: true // For Java apps
}
}
}
post {
always {
echo 'Cleaning up workspace...'
cleanWs()
}
success {
echo 'Release branch successfully processed!'
// Additional steps like sending notifications can be added here
}
failure {
echo 'Error occurred while processing the release branch.'
// You can add failure notifications or reports here
}
}
}
Step 7: Merge the Release Branch to main
Once the release branch has passed all testing and is ready for production, merge the release branch into main
(or master
).
# Switch to the master (main) branch
git checkout master
# Merge the release branch into master
git merge release/v1.0
At this point, Jenkins will trigger the production deployment pipeline, deploying the code to the live environment.
CI/CD Pipeline for main
Branch with Manual Approval
Use Case: Automatically deploy code from the main
branch to the production environment after a successful merge from the release branch, but with a manual approval step.
Automation Steps:
After merging the release branch into
main
, trigger the pipeline to:Build the final production artifacts.
Wait for manual approval to proceed with deployment.
Once approved, deploy the application to the production environment.
Run post-deployment health checks to ensure the application is running correctly.
Benefits:
Provides an additional layer of verification through manual approval before production deployment.
Reduces the risk of unintended changes being deployed to production by requiring human intervention.
Production Deployment Pipeline Example:
pipeline {
agent any
environment {
MAIN_BRANCH = 'master' // Use 'main' if that's your default branch
DEPLOY_SCRIPT = './deploy-to-prod.sh' // Script for production deployment
}
stages {
stage('Build Production Artifacts') {
when {
branch "${MAIN_BRANCH}" // Only run when on main branch
}
steps {
echo 'Building final production artifacts...'
sh 'mvn clean package'
}
}
stage('Manual Approval for Production Deployment') {
input {
message "Approve deployment to production?" // Prompt for manual approval
ok "Deploy to Production" // Button text for approval
}
steps {
echo 'Manual approval received. Proceeding to deploy to production...'
}
}
stage('Deploy to Production') {
steps {
echo 'Deploying application to production...'
sh "${DEPLOY_SCRIPT}" // Custom script for production deployment
}
}
stage('Post-Deployment Health Checks') {
steps {
echo 'Running post-deployment health checks...'
sh './check-app-health.sh' // Custom script for verifying app health
}
}
}
post {
success {
echo 'Production deployment completed successfully!'
// Optionally, send notifications about successful deployment
}
failure {
echo 'Production deployment failed.'
// Optionally, send failure notifications
}
always {
cleanWs() // Clean workspace after the job completes
}
}
}
Step 8: Tag the Release
After deploying the release to production, create a tag to mark the specific version of the release.
# Tag the release in the master branch
git tag -a v1.0 -m "Release version 1.0"
# Push the tag to the remote repository
git push origin v1.0
Step 9: Merge the Release Branch Back into develop
To ensure that any final changes or fixes in the release branch are not lost, merge the release branch back into develop
.
# Switch to the develop branch
git checkout develop
# Merge the release branch into develop
git merge release/v1.0
Step 10: Handle Hotfixes
If a critical bug is found in production, create a hotfix branch from main
, apply the fix, and merge it back into both main
and develop
.
# Create a hotfix branch from master
git checkout -b hotfix/critical-issue master
# Make the fix and commit
git add .
git commit -m "Fix critical production issue"
# Merge the hotfix back into master
git checkout master
git merge hotfix/critical-issue
# Merge the hotfix back into develop
git checkout develop
git merge hotfix/critical-issue
Once the hotfix is tested, Jenkins will deploy it to production and ensure both the main
and develop
branches are up to date.
CI/CD Pipeline for Hotfix Branches:
Use Case: Deploy urgent hotfixes to production directly from the hotfix branch.
Automation Steps:
When a hotfix branch is created, automate the process to:
Build the code and run any critical tests.
Deploy the hotfix to production immediately.
Merge the hotfix back into both
develop
andmain
to ensure consistency.
Benefits:
- Ensures that production issues are resolved quickly without waiting for the next release cycle.
Hotfix to Production Deployment Pipeline Example:
pipeline {
agent any
environment {
HOTFIX_BRANCH = env.BRANCH_NAME // Assuming the pipeline is triggered by the hotfix branch
MAIN_BRANCH = 'master' // Name of your main branch (can be 'master' or 'main')
DEVELOP_BRANCH = 'develop' // Name of your develop branch
TRIVY_IMAGE = 'your-app-image:hotfix' // Docker image for hotfix
}
stages {
stage('Validate Hotfix Branch') {
steps {
script {
if (!env.BRANCH_NAME.startsWith('hotfix/')) {
error('This pipeline should only run on hotfix branches.')
} else {
echo "Processing hotfix branch: ${env.BRANCH_NAME}"
}
}
}
}
stage('Checkout Hotfix Branch') {
steps {
echo 'Checking out the hotfix branch...'
git branch: "${HOTFIX_BRANCH}", url: 'https://github.com/your-repo-url.git'
}
}
stage('Build Hotfix') {
steps {
echo 'Building the hotfix...'
sh 'mvn clean package' // Example build command
}
}
stage('Run Hotfix Tests') {
steps {
echo 'Running tests on the hotfix...'
sh 'mvn test'
}
}
stage('Security Scan') {
steps {
echo 'Running security scan on the hotfix...'
sh "trivy image ${TRIVY_IMAGE}"
}
}
stage('Deploy Hotfix to Production') {
steps {
echo 'Deploying the hotfix to production...'
sh './deploy-to-prod.sh' // Custom script to deploy hotfix to production
}
}
stage('Merge Hotfix into Master') {
steps {
echo 'Merging hotfix into master...'
script {
// Merge hotfix branch into master branch
sh '''
git checkout ${MAIN_BRANCH}
git pull origin ${MAIN_BRANCH}
git merge ${HOTFIX_BRANCH}
git push origin ${MAIN_BRANCH}
'''
}
}
}
stage('Merge Hotfix into Develop') {
steps {
echo 'Merging hotfix into develop...'
script {
// Merge hotfix branch into develop branch
sh '''
git checkout ${DEVELOP_BRANCH}
git pull origin ${DEVELOP_BRANCH}
git merge ${HOTFIX_BRANCH}
git push origin ${DEVELOP_BRANCH}
'''
}
}
}
}
post {
success {
echo 'Hotfix successfully applied, merged into main and develop!'
// Optional: send notification to the team
}
failure {
echo 'Hotfix process failed. Please investigate.'
// Optional: send failure notification
}
always {
cleanWs() // Clean up workspace after the job
}
}
}
Merging Best Practices in Git Flow:
Frequent Merges into
develop
:
Merge feature branches intodevelop
often to avoid complex conflicts and keep the codebase up to date.Use Pull Requests:
Always merge via pull requests to encourage peer reviews, ensuring code quality and adherence to standards.Keep Feature Branches Small:
Keep feature branches short-lived and focused on specific tasks to reduce complexity and simplify merges.Test Before Merging:
Run automated tests as part of your CI pipeline before merging intodevelop
ormain
to prevent introducing bugs.Rebase Regularly:
Rebase feature branches ontodevelop
regularly instead of merging to keep the commit history clean.Squash Commits:
Squash commits when merging to create a clean, meaningful commit history.Merge Back into
develop
andmain
:
After a release or hotfix is merged intomain
, merge it back intodevelop
to keep branches in sync.Resolve Conflicts Early:
Address merge conflicts immediately to avoid escalating complexity and potential issues.
Use Cases of Git Flow for Large Teams:
Complex Projects with Multiple Features:
Git Flow allows developers to work on separate feature branches, ensuring isolated development without affecting the main codebase.Organized Release Management:
Release branches help teams finalize code for production while allowing ongoing development on other features.Quick Fixes for Production Issues:
Hotfix branches enable rapid fixes for critical production bugs without waiting for the next release.CI/CD Integration:
Git Flow integrates well with CI/CD pipelines, allowing large teams to automate testing, building, and deployment for smoother workflows.
In conclusion, Git Flow provides a structured approach to managing code for large teams and complex projects by using a mix of long-lived and short-lived branches. It ensures clear separation between production and development environments, streamlining workflows and collaboration. While its complexity may be unnecessary for smaller projects, Git Flow enhances stability and quality in software releases.
"Tell me and I forget, teach me and I may remember, involve me and I learn." – Benjamin Franklin
Thank you, Happy Learning!
Subscribe to my newsletter
Read articles from Subbu Tech Tutorials directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by