Check whether a Git branch has been merged
Check commit ancestry against an explicit target, distinguish squash merges from ordinary merges, and review a branch before deleting it.
Use git branch --merged main to list local branches whose tips are reachable from main. This answers an ancestry question: all commits reachable from the listed tip are already reachable from the target.
Inspect local and remote-tracking branches
git branch --merged main
git branch --no-merged main
git fetch origin
git branch -r --merged origin/main
Without an explicit target, --merged and --no-merged use HEAD. Supplying main avoids switching branches just to run the check. Remote-tracking refs describe the last fetched state; they are not a live query of the server.
Use an exit status in a script
git merge-base --is-ancestor feature-x main
result=$?
case "$result" in
0) echo "feature-x is reachable from main" ;;
1) echo "feature-x is not reachable from main" ;;
*) echo "Could not check ancestry" >&2; exit "$result" ;;
esac
Status 1 means the ancestry test is false. Other failures, such as a misspelled ref, should not be reported as an unmerged branch.
Account for squash merges and cherry-picks
A squash merge can integrate a feature's content without making the original feature commits ancestors of main. The ancestry checks can therefore report the branch as unmerged even when its changes were accepted.
git cherry main feature-x
This compares individual patches: - marks a patch-equivalent commit upstream, and + marks one without such an equivalent. It does not generally recognize several feature commits combined into one squash commit. Review the pull request, the squash commit, and the resulting content before deciding that the branch is redundant.
Review before deleting
git branch -d feature-x checks whether the tip is merged into its configured upstream, or into HEAD if no upstream is set. That target may differ from the main you just inspected. Ancestry also says nothing about whether a branch name is still needed by a workflow or another developer.
For a verified squash integration, deletion may require -D. Preserve a backup ref if the original history matters, and confirm the branch is no longer in use before forcing deletion.
Find integration clues
git log --merges --oneline main
git log --grep='feature-x' --oneline main
git branch -r --no-merged main
Merge messages can help locate an integration date, but names are not guaranteed to appear, and fast-forward or squash integrations need not leave an ordinary merge commit. The last command lists remote-tracking branches needing review; it is not a deletion instruction.
See git-branch, git-merge-base, and git-cherry.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan