Have you ever encountered this message while attempting to delete a branch?
$ git branch -d docs
error: The branch 'docs' is not an ancestor of your current HEAD.
If you are sure you want to delete it, run 'git branch -D docs'
This occurs when the branch you’re currently on doesn’t have the branch you’re trying to delete merged in. It’s one of the many ways Git endeavors to safeguard your data. So, how can you determine if a given branch (or commit) has been merged into your current branch without attempting to delete it?
The git branch command offers several flags to address this issue. The –contains flag identifies whether a specific commit has been incorporated into your branch. Perhaps you have a commit SHA from a patch you believed you applied, or you’re simply checking if a commit for your favorite open-source project that reduces memory usage by 75% has been integrated.
$ git log -1 tests
commit d590f2ac0635ec0053c4a7377bd929943d475297
Green all around, finally.
$ git branch --contains d590f2
tests
master
From these results, we can ascertain that commit d590f2 has been merged into both the tests and master branches.
Now, returning to the original issue of determining if a branch has been merged in. The –merged and –no-merged flags can provide this information. The former indicates which branches have the specified treeish merged in, while the latter does the opposite.
In this case, the docs branch is not fully merged into the master branch:
$ git branch --merged docs
docs
$ git branch --no-merged docs
config
master
tests
$ git branch -d docs
error: The branch 'docs' is not an ancestor of your current HEAD.
If you are sure you want to delete it, run 'git branch -D docs'.
$ git branch -D docs
Deleted branch docs (884583c).
If you’re feeling adventurous, you can use a combination of git rev-parse and git rev-list to determine if a commit is in the history of a given branch or not. rev-parse converts a treeish into its corresponding SHA, while rev-list can display commits in various formats.
$ git rev-list master | grep $(git rev-parse docs)
$ git rev-list master | grep $(git rev-parse tests)
d590f2ac0635ec0053c4a7377bd929943d475297
The first command returns nothing because the HEAD commit in docs doesn’t exist in the timeline for the master branch yet. Conversely, grep finds the HEAD commit for tests in master as expected.
Hopefully, this saves you some time when managing multiple branches and wondering if they’ve been merged in yet. If you have other suggestions for handling this situation, feel free to share them!