# Fast-Forward Merge

URL: https://softwaredictionary.org/terms/fast-forward-merge
Category: Version Control
Last updated: 2026-10-03

In short: A fast-forward merge happens when the target has no new commits since the other branch split off, so Git just moves its pointer ahead with no merge commit.

## What is a fast-forward merge?

Suppose you create a `feature` branch from `main`, make three commits, and nobody adds anything to `main` in the meantime. History is a straight line: `main` is just behind `feature`. Merging `feature` into `main` doesn't need to combine anything, so Git moves the `main` pointer to the last feature commit. That is a fast-forward, and the result is linear history with no extra merge commit.

If `main` has moved on since the branch was created, the two lines have diverged and a fast-forward is impossible. Git then either creates a merge commit with two parents, or you rebase the branch onto the new `main` first, which makes it fast-forwardable again. `git pull` faces the same choice when your local branch and the remote branch have both changed.

Teams choose policies with flags. `git merge --ff-only` refuses to merge unless it can fast-forward, keeping history strictly linear. `git merge --no-ff` always creates a merge commit, even when a fast-forward is possible, so each feature appears as a visible group of commits. Hosting platforms offer similar choices, such as GitHub's merge, squash and rebase buttons.

A common misconception is that a fast-forward merge loses information. No commits are changed or removed; the branch pointer just moves. What disappears is the record that the commits were developed on a separate branch, which is why some teams prefer merge commits for features and fast-forwards for small updates.

## Key takeaways

- A fast-forward moves the branch pointer instead of creating a merge commit.
- It is only possible when the target branch hasn't diverged.
- Rebasing a branch onto the latest main makes it fast-forwardable.
- --ff-only enforces linear history; --no-ff always records a merge commit.
- No commits are lost, only the visible grouping of a feature branch.

## Example: Fast-forward versus a merge commit

```bash
git switch main
git merge feature
# Updating 41d0e77..9f2c1ab
# Fast-forward              ← main simply moved to feature's last commit

git merge --ff-only hotfix  # merge only if it can fast-forward, otherwise stop
git merge --no-ff feature   # always create a merge commit for the feature

git config --global pull.ff only   # make 'git pull' refuse non-fast-forward merges
```

## Frequently asked questions

**When does Git do a fast-forward merge?**

When the branch being merged into has no commits that the other branch lacks, meaning history hasn't diverged. Git then moves the pointer forward by default instead of creating a merge commit.

**What does --no-ff do?**

It forces Git to create a merge commit even when a fast-forward would be possible, so the feature's commits stay grouped under one merge in the history.

**Fast-forward or merge commit: which is better?**

It is a team preference. Fast-forwards and rebases give a clean, linear history that is easy to read and bisect. Merge commits preserve when and how features were integrated. Many teams squash or rebase small changes and use merge commits for larger features.

---

Software Dictionary: https://softwaredictionary.org/ · https://softwaredictionary.org/llms.txt
