Graphite Reviewer is now Diamond

Merge strategies

Greg Foster
Greg Foster
Graphite software engineer
Try Graphite


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.

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

NOTE: 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

NOTE: 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

NOTE: 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.

While Git offers powerful merge strategies, managing complex development workflows can still be challenging. Graphite enhances Git by introducing features that streamline the development process, particularly through stacked pull requests.

  • Stacked pull requests: Graphite allows developers to break down large changes into smaller, manageable PRs that build upon each other. This approach simplifies code reviews and reduces merge conflicts.

  • Merge queue: Graphite's merge queue automates the process of merging stacked PRs. It sequentially merges each PR after ensuring all checks pass, maintaining a clean and stable main branch.

  • CLI and VS Code integration: With a dedicated CLI and a VS Code extension, Graphite integrates seamlessly into your development environment, facilitating tasks like creating, modifying, and merging PRs.

  • GitHub synchronization: Graphite is built on top of GitHub, so that all PRs, reviews, and comments are up-to-date across platforms.

By incorporating Graphite into your workflow, you can enhance collaboration, maintain a cleaner commit history, and accelerate the development cycle. For more information, visit graphite.dev.

Mastering git merge strategies is crucial for maintaining a clear and efficient project history. by understanding and appropriately applying strategies like fast-forward, recursive, squash, and rebase, developers can ensure smoother collaboration and streamlined workflows. each strategy offers distinct advantages, and selecting the right one depends on the specific needs of your project. for instance, squash merges can simplify histories, while recursive merges preserve detailed commit logs. ultimately, the key is to choose the strategy that best aligns with your team's workflow and project goals.

Built for the world's fastest engineering teams, now available for everyone