Git Merge Patterns for Main and Release Branches

2025/02/023 min read
bookmark this
Responsive image

Table of Contents

  1. Introduction
  2. The Main Branch: Squash and Merge
  3. Other Cases for Main
  4. The Release Branch: Fast-Forward
  5. Syntax: Syncing Main to Release
  6. Handling Hotpatches
  7. 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 blame will point to the a feature instead of individual commit fixed 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-ff to create a dedicated "Merge node" to show exactly when a release happened.
  • Squash to Release: Some teams squash all of main into 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!