Skip to content

/errors/git/branch-is-not-fully-merged

error: the branch 'feature' is not fully merged

verified onenvironmentlocal · linux 6.18.44-fc-v153 x64 · GNU bash 5.2.21 · git version 2.43.0updated
tool
Git
exit code
1
versions
Git 2.x
os
linux, macos, windows

error: the branch 'feat' is not fully merged means git branch -d feat found commits on feat that no other branch you are using contains. Git stops so you do not lose them. Merge the branch, or, if you are sure the work is already elsewhere, delete it with git branch -D feat. The command exits with status 1.

Reproduce it

bash
git init -q -b main demo && cd demo
git -c user.name=demo -c user.email=demo@example.com commit -q --allow-empty -m "Initial commit"
git switch -q -c feat
git -c user.name=demo -c user.email=demo@example.com commit -q --allow-empty -m "Work on feat"
git switch -q main
git branch -d feat

Output · exit 1

error: the branch 'feat' is not fully merged.
If you are sure you want to delete it, run 'git branch -D feat'

The safe delete checks whether the tip of feat is reachable from HEAD, or, when the branch has an upstream, from that upstream. Here feat has one commit that main lacks.

Fixes

1. Merge, then delete

If the work should be kept, merge it into the branch you are on, then the safe delete succeeds:

bash
git init -q -b main demo && cd demo
git -c user.name=demo -c user.email=demo@example.com commit -q --allow-empty -m "Initial commit"
git switch -q -c feat
git -c user.name=demo -c user.email=demo@example.com commit -q --allow-empty -m "Work on feat"
git switch -q main
git -c user.name=demo -c user.email=demo@example.com merge -q --no-ff -m "Merge feat" feat
git branch -d feat

Output

Deleted branch feat (was ba21208).

2. Look before you force

List the commits that only the branch has:

bash
git log --oneline main..feat

An empty list means nothing would be lost. A list means those commits exist nowhere else.

3. Force when the work lives elsewhere

If the pull request was squash-merged or rebased on the hosting service, the content is in main under different hashes. Git cannot tell, so -d refuses. After checking the pull request is merged, delete with force:

bash
git branch -D feat

Recover a deleted branch

git branch -D prints Deleted branch feat (was abc1234). Recreate it with git branch feat abc1234. If you lost the output, git reflog shows where HEAD was recently, and the hash of the last commit on feat is in that list.

Which delete to use

SituationCommand
Branch merged with a merge commit or fast-forwardgit branch -d NAME
Branch squash-merged or rebased on the remotegit branch -D NAME after checking the PR is merged
Branch has unique work you want to keepMerge or push it first, then git branch -d NAME
Remove the branch on the remote as wellgit push origin --delete NAME

Prevention

Run the delete from the branch you merged into, and keep an upstream set (git push -u) so Git compares with the remote branch. Many teams delete branches right after the merge on the hosting service and clean local ones with git fetch --prune, then review the leftovers with git branch --no-merged main.

FAQ

What is the difference between git branch -d and -D?

-d deletes a branch only when its commits are merged, and refuses otherwise. -D is the same as --delete --force: it deletes the branch whatever its state.

Why does a squash-merged branch count as not merged?

A squash merge creates one new commit with the same changes. The original commits are not in main's history, so Git cannot see that the branch is merged.

Can I get a branch back after git branch -D?

Usually yes. Git prints the old hash when it deletes a branch, and git reflog lists recent positions of HEAD. git branch NAME HASH recreates it, until old commits are garbage collected.

Sources