Git Merge Patterns for Main and Release Branches
Table of Contents
- Introduction
- The Main Branch: Squash and Merge
- Other Cases for Main
- The Release Branch: Fast-Forward
- Syntax: Syncing Main to Release
- Handling Hotpatches
- Conclusion
Introduction
This blog demonstrates a clean and efficient Git workflow tailored for small teams. We will focus on keeping the main branch history readable while ensuring the release branch remains a stable mirror of production.
The Main Branch: Squash and Merge
When working on features or bugs, developers often create dozens of "work-in-progress" commits. To keep the main branch clean, we use the Squash and Merge pattern. This collapses all commits from a branch into a single, high-quality commit on main.
- Feature Branches (
feature/description): Use this for new development. - Bug Branches (
bugs/description): Use this for fixing issues found in development.
Other benefits
- Feature Reversion: If feature introduced a failure, squashing make it easier to revert the change.
- Simplified "Git Blame":
git blamewill point to the a feature instead of individual commitfixed typo - Avoiding "Broken" Intermediate Commits: sometime in feature branch dev fixed build or unit-test, if not use squash and keep all history, main branch will contains "broken" build commits.
Other Cases for Main
Beyond features and bugs, you might merge into main for:
- Refactoring: Code cleanup that doesn't change functionality.
- Documentation: Updates to README files or API docs.
- CI/CD Updates: Modifying GitHub Actions or deployment scripts.
- Dependency Updates: Merging automated PRs (like Dependabot) to keep libraries secure.
Example: create feature branch
# Ensure you are on main and up to date
git checkout main
git pull origin main
# Create and switch to a new feature branch
git checkout -b feature/describe-feature
The Release Branch: Fast-Forward
For small teams, we want the release branch to be easy to manage. We use the Fast-Forward pattern, which keeps all commit history identical between main and release.
Alternative Approaches:
- Merge Commits: Some teams use
--no-ffto create a dedicated "Merge node" to show exactly when a release happened. - Squash to Release: Some teams squash all of
maininto one single "Version 1.0" commit on the release branch, though this makes tracking individual changes harder.
Syntax: Syncing Main to Release
To move your verified code from main to release using the fast-forward pattern, run:
git checkout release
git merge main --ff-only
git push origin release
Conclusion
By using Squash for development and Fast-Forward for releases, your team maintains a professional, readable history that is easy to debug. Hopefully, you find this pattern helpful for your team's workflow!