Skip to content

/glossary/git/fast-forward-merge

What is a fast-forward merge in Git?

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · git version 2.55.0.windows.5updated
tool
Git
versions
Git 2.x
os
linux, macos, windows

A fast-forward merge happens when the branch you merge into has no commits of its own since the other branch split off. Git then does not create a merge commit: it moves the branch pointer forward to the other branch's latest commit, and the history stays a straight line. git merge fast-forwards whenever it can; --no-ff forces a merge commit, and --ff-only refuses anything that is not a fast-forward.

See it

bash
git init -q -b main repo && cd repo
echo a > a && git add a && git commit -qm "base"
git switch -q -c feature
echo b > b && git add b && git commit -qm "feature work"
git switch -q main
git merge feature
git log --oneline --graph

Output

Updating 6ea0488..ccb3ac5
Fast-forward
 b | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 b
* ccb3ac5 feature work
* 6ea0488 base

main had no new commits, so git merge printed Fast-forward and main now points at the feature commit.

When it cannot fast-forward

bash
git init -q -b main repo && cd repo
echo a > a && git add a && git commit -qm "base"
git switch -q -c feature && echo b > b && git add b && git commit -qm "feature work"
git switch -q main && echo c > c && git add c && git commit -qm "hotfix on main"
git merge --ff-only feature

Output · exit 128

hint: Diverging branches can't be fast-forwarded, you need to either:
hint:
hint: 	git merge --no-ff
hint:
hint: or:
hint:
hint: 	git rebase
hint:
hint: Disable this message with "git config set advice.diverging false"
fatal: Not possible to fast-forward, aborting.

Both branches have new commits, so only a real merge (or a rebase) can combine them.

The same message appears from git pull when pull.ff only is set; the Not possible to fast-forward page covers the fixes.

Fast-forward and git push

Pushes follow the same rule: by default a remote branch only accepts updates that fast-forward it, so your local branch must contain the remote tip. When it does not, the push is rejected as non-fast-forward (failed to push some refs). Pull or rebase to include the remote commits, then push again. A force push skips the check, which is why --force-with-lease exists.

Nothing to merge

If the other branch has no commits that the current branch lacks, Git neither fast-forwards nor merges:

bash
git init -q -b main repo && cd repo
echo a > a && git add a && git commit -qm "base"
git branch old
git merge old

Output

Already up to date.

Options

CommandResult
git merge BFast-forward if possible, otherwise a merge commit
git merge --no-ff BAlways a merge commit, which records that a branch existed
git merge --ff-only BFast-forward or fail; never a merge commit
git config merge.ff onlyMake --ff-only the default for git merge
git config pull.ff onlyMake git pull fast-forward only

Many teams use --no-ff for feature branches so each feature appears as one merge commit, and --ff-only for git pull so local history never gets accidental merge commits.

FAQ

Is a fast-forward merge bad?

No. It keeps history linear and loses nothing. The only thing missing is a merge commit that records that a branch existed, which some teams want for feature branches and get with --no-ff.

What does Already up to date mean after git merge?

The branch you merge is already contained in the current branch, so there is nothing to fast-forward and nothing to merge.

How do I fix fatal: Not possible to fast-forward, aborting?

Both branches have new commits. Rebase your branch onto the other one, or allow a real merge by running the merge or pull without --ff-only.

Sources