error: the branch 'x' is not fully merged from git branch -d x means the branch has commits that your current branch does not contain, so deleting it would leave them without a name. List them with git log main..x; merge them if you need them, or delete the branch with git branch -D x if you do not.

Lower-case -d is the safe delete and refuses on purpose; upper-case -D deletes regardless. Use -D only after you have looked at what it throws away.

The error

PS> git branch -d x
error: the branch 'x' is not fully merged
hint: If you are sure you want to delete it, run 'git branch -D x'
hint: Disable this message with "git config advice.forceDeleteBranch false"

This is the text Git for Windows 2.45.2 printed. The exact capitalisation and the hint lines vary between Git versions, so search for the words in the middle of the line.

Why it happens

A branch is only a name pointing at a commit. git branch -d checks whether that commit is reachable from the branch you are on. If it is, the commits survive in the other history and removing the name loses nothing. If it is not, those commits would be left with no branch name pointing at them, so Git stops and asks you to say -D explicitly.

A pushed branch is treated differently. In a second test, feature was pushed with -u and not merged into main; from main, git branch -d feature deleted it with a warning, because its commit is in the remote-tracking branch:

PS> git branch -d feature
warning: deleting branch 'feature' that has been merged to
         'refs/remotes/origin/feature', but not yet merged to HEAD
Deleted branch feature (was f363963).

So the refusal means the commits are in neither your current branch nor the branch's upstream: the work was never merged into the branch you are on (perhaps into another one), or the branch holds experiments you never meant to merge.

The fix

First see exactly which commits are at stake:

PS> git log --oneline main..x
ae40e64 login page
PS> git branch --no-merged
  x

If you want them, merge and the safe delete then succeeds:

PS> git merge --no-edit x
Updating 663023e..ae40e64
Fast-forward
 login.txt | 1 +
PS> git branch -d x
Deleted branch x (was ae40e64).

If they are throwaway work, force the delete:

PS> git branch -d y
error: the branch 'y' is not fully merged
PS> git branch -D y
Deleted branch y (was 1ccac44).

Keep the hash Git prints after was: a forced delete can be undone by creating the branch again at that commit. In a repeat run, git branch -D y printed (was ac1e530) and git branch y ac1e530 brought the branch back with its commit.

How it was reproduced

Git for Windows 2.45.2 on Windows 11, Windows PowerShell 5.1, in a throwaway repository. Branch x got one commit that main did not have; git branch -d x exited with code 1. After a fast-forward merge the same command deleted it. A second branch y with an unmerged commit was refused by -d and removed with -D.

Frequently asked

How do I delete a git branch that is not fully merged?
Check what you would lose with git log --oneline main..branch, then run git branch -D branch. The capital D forces the delete.
Can I undo git branch -D?
Yes, if you have the hash it printed after was. Create the branch again at that commit with git branch name hash; in the test the branch came back with its commit.
What is the difference between git branch -d and -D?
-d deletes a branch whose commits are already in the current branch, or (with a warning) in the branch's upstream on the remote. -D deletes it regardless and leaves its unmerged commits without a branch name; note the hash it prints so you can recreate the branch.

More decoded errors in the Fixes category. For how branches and merges fit together, see Git branches explained.