Merge strategies

Greg Foster
Greg Foster
Graphite software engineer


Note

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


Understanding how to effectively merge code is essential for software developers working in teams or managing multiple streams of work. This documentation explores various Git merge strategies, detailing their use cases, technical details, and providing support resources to enable developers to choose the most suitable approach for their project needs.


Core Concepts

Git provides several merge strategies to integrate changes from different branches. These strategies differ in how they handle conflicts and history, which can influence the readability of the project history and the ease of tracking changes.

The Fast-Forward merge is the simplest strategy. If the branch being merged into has no new commits since the feature branch was created, Git will simply move the HEAD pointer forward. This strategy is ideal when the feature branch history is linear and no additional commits have been made to the main branch.

Terminal
git checkout main
git merge feature_branch

The Recursive merge strategy is used when there are new commits on the base branch. Git will create a new commit that combines the changes of the merged branches. This strategy is beneficial when you want to preserve the history of a feature branch with multiple contributors.

Terminal
git checkout main
git merge --no-ff feature_branch

The Squash merge strategy takes all commits from the feature branch and combines them into a single commit to be added to the base branch. This approach is suitable when you want a clean history in the main branch but the feature branch history is complex.

Terminal
git checkout main
git merge --squash feature_branch
git commit -m "Merge feature_branch with squash"

Rebasing rewrites the feature branch's history to appear as if it was built off the latest commit in the base branch. This strategy is beneficial when you want to integrate the latest main branch changes into your feature branch without a merge commit.

Terminal
git checkout feature_branch
git rebase main

Below are scenarios demonstrating how each merge strategy might be used:

Terminal
git checkout main
git merge feature_branch

Use this when the feature branch history is linear and no additional commits have been made to the main branch.

Terminal
git checkout main
git merge --no-ff feature_branch

Adopt this strategy when you want to preserve the history of a feature branch with multiple contributors.

Terminal
git checkout main
git merge --squash feature_branch
git commit -m "Merge feature_branch with squash"

This approach is suitable when you want a clean history in the main branch but feature branch history is complex.

Terminal
git checkout feature_branch
git rebase main

Rebasing is beneficial when you want to integrate the latest main branch changes into your feature branch without a merge commit.

During a merge, conflicts may occur. Conflict resolution is a manual process where developers must choose which changes to keep.

Merge commits are created by default during a merge. They have two parent commits and are a record of a merge event.

The choice of merge strategy impacts the project history. A non-fast-forward merge always creates a merge commit, preserving the exact history, while rebasing creates a linear history that can be easier to follow.

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