Command Reference

git merge Tutorial

Explains the purpose of git merge, the difference between fast-forward and merge commits, and how to handle conflicts.

Who This Is For
  • Collaborators integrating branch history
Prerequisites
  • A basic model of branch divergence
  • Comfort reading what a merge commit means
Common Risks
  • Forcing through conflicts without understanding them
  • Blurring the boundary between merge and rebase

The short version

git merge integrates another branch into the current branch without requiring you to rewrite existing commits.

When it is a good fit

  • merging a feature branch back into main
  • preserving the real branch integration history
  • integrating shared branches without rewriting history

Two common outcomes

Fast-forward

If the current branch has not diverged, Git can simply move the branch pointer forward.

Merge commit

If both branches moved forward independently, Git creates a merge commit that records where the histories joined.

How merge expresses historyMerge keeps the original commits and adds a new merge commit that records the point where the two branches were joined.
Before merge
main
ABC
feature
BDE
After merge
main
ABCM
feature
BDEM

If you compare this picture with the rebase diagram, the key difference is that merge preserves the branch shape and adds a new integration point instead of replaying commits into a new linear sequence.

Basic workflow

git checkout main
git fetch origin
git merge feature/login

Common flags and strategies

--ff-only

Only allow fast-forward merges. If the histories diverged, the merge fails instead of creating a merge commit.

git merge --ff-only origin/main

--no-ff

Create a merge commit even when a fast-forward would be possible. Teams sometimes use this to preserve the explicit branch boundary.

git merge --no-ff feature/login

Handling conflicts

git status
# resolve conflicts
git add <resolved-files>
git merge --continue

Abort if needed:

git merge --abort

When merge is a better choice than rebase

  • the branch is already shared
  • you want to preserve the integration graph
  • your team values non-rewritten collaboration history

A practical decision rule

If your question is “Should I integrate this whole branch history here?”, merge is usually the more natural tool.

If your question is “Should I rewrite how my branch history is expressed?”, that usually points more toward rebase.

What problem this command solves in a workflow

git merge directly affects history shape, ref position, or relationships between commits. The first decision is whether you are organizing private local history or touching history that is already shared with others.

Typical use cases

  • Use git merge when integrating branches, undoing changes, selecting commits, or reshaping a sequence of commits.
  • Put git merge inside a “backup first, mutate second, verify last” flow so higher-risk history operations stay recoverable.
  • Use git merge to understand ancestry, recovery paths, and commit causality during conflict resolution or post-incident analysis.

Diagram view

What history commands act onHistory-oriented commands revolve around commit sequences, branch pointers, and ancestry. The difference is whether they add history, move refs, or rewrite an existing sequence.
Inputs
Commit sequenceCurrent branchAncestry
Results
New commit relationsMoved refsRecovery path
The highest-value preflight question for this category is simple: “Has this history already been shared?”

Special cases and boundaries

  • The most expensive failure mode in history commands is rewriting or moving commits that other people already depend on.
  • If the operation might affect team flow, run git status, git log --oneline --graph, and git reflog first so the recovery path is visible.
  • When in doubt, create a backup branch before continuing so you preserve an obvious way back.
  • During conflicts, do not only inspect files. Reconfirm which side of history the merge is supposed to preserve.

Try it yourself

Exercise: compare fast-forward with a merge commit

This is where merge stops being just a syntax choice and starts becoming a history-shape choice.

Setup
git switch -c lab/merge-demo
# create a feature branch and make one commit on each side
Try it
  1. First try `git merge --ff-only` when there is no divergence.
  2. Then create divergence by adding commits on both main and feature.
  3. Run `git merge feature/demo` and inspect the result with `git log --oneline --graph --decorate -8`.
What happens next
  • Without divergence, Git only moves the branch pointer forward.
  • With divergence, Git creates a new merge commit.
  • The graph explicitly records where two lines of work joined.
Common mistake checks
  • If you assume merge commits are automatically “messy,” you miss the value of preserving integration history.
  • During conflicts, ask which historical relationship you are trying to preserve, not only which file lines to keep.
  • If your platform enforces linear history, check that policy before choosing merge.