[!TIP] Rule of Thumb: Use Squash for feature branches (to keep history clean) and Merge Commits for releases (to preserve history).

The Three Ways to Combine Code

When you run git merge feature-login, Git doesn’t just “mash” files together. It has to decide what the history looks like.

There are three main strategies:

  1. Fast-Forward: Just move the pointer.
  2. Merge Commit (Recursive): Create a new commit with two parents.
  3. Squash: Combine all changes into a single new commit.

Interactive: Merge Strategy Playground

See how different merge strategies affect your commit history.

Status: Initial State

1. Fast-Forward (The Default)

If your feature branch is directly ahead of main (meaning main hasn’t changed since you branched off), Git doesn’t need to create a new commit. It simply slides the pointer forward.

git checkout main
git merge feature-login
  • Pros: Clean, linear history.
  • Cons: You lose the context that a “feature branch” ever existed.

2. Merge Commit (–no-ff)

This forces Git to create a new commit, even if it could have fast-forwarded. This preserves the “bubble” shape in the history graph.

git merge --no-ff feature-login
  • Pros: Preserves the existence of the feature branch. Good for grouping related commits.
  • Cons: Can clutter history if used for tiny changes.

3. Squash Merge

Squashing takes all the commits from your feature branch (F1, F2, F3) and compresses them into one single commit on main.

git merge --squash feature-login
# Note: --squash stops before committing. You must commit manually.
git commit -m "Add login feature"
  • Pros: Ultra-clean main history. One feature = One commit.
  • Cons: You lose the granular history of how the feature was built (the “oops fix typo” commits are gone).

Summary: Which to Choose?

Strategy Command Use Case
Fast-Forward git merge Personal projects, small updates.
Merge Commit git merge --no-ff Releases. Merging develop into main to mark a version.
Squash git merge --squash Pull Requests. Merging a feature branch into main.