tl;dr: Since your goal is to know which local branches you are done working on and can be deleted, the command you tried isn't sufficient. You'll need to do something else first, or use a different method entirely.
Explanation:
I think the source of your question really comes from the wording used by the branch
option --merged
, which is confusing since "merged" means something slightly different in Git than it does in English.
The documentation for --merged
states (emphasis mine):
With --merged, only branches merged into the named commit (i.e. the branches whose tip commits are reachable from the named commit) will be listed.
For example, after you merge my-branch
into master
, my-branch
is going to appear as "merged" when you run the command git branch --merged master
, but it doesn't appear in the list because you merged it in, it appears because after you merged it in the branch is now reachable from master
. Any new branch you create from master
without adding new commits is of course also reachable, and consequently will also be considered "merged" by Git. Note, after merging my-branch
into master
, if you add a new commit to my-branch
, it will no longer appear as "merged" from Git's POV even though you previously did "merge" it. The point here is whether or not you actually ran git merge
somewhere to merge a branch in, isn't necessarily relevant to whether or not Git considers the branch "reachable".
Possible Alternatives:
Simple: There is a very simple solution that would enable you to keep doing what you're doing. Any time you create a new branch, add an empty commit to it, perhaps with some comment that may be useful. For example:
git fetch
# make your branch...
# Add an empty commit:
git commit --allow-empty -m "wip: Improve performance by refactoring"
By adding a blank commit it will no longer be reachable from master
. When you're ready to work on that branch just amend (and remove the "wip: " prefix in the subject), or reset back a commit before you make your first commit on that branch.
Better? If you use a SCM tool to merge your branches into master
rather than doing it locally, and if your workflow is to delete your remote branches after they are merged in (which really ought to be the default and most tools offer this as a selectable option when completing a PR), then you can (and probably should) prune your remote tracking branches, and then you can identify which local branches used to have a remote tracking branch but no longer do. Here's an example of this.
Simplest? What if you just delete all "merged" branches, and use some other mechanism to determine what you have to work on (e.g. issue tracker or project management tool). Having a bunch of branch names sitting there with no new commits on them isn't necessarily helping you, other than to remind you that you need to do it.
Creative with a Caveat: Of all the solutions, I think this one is probably what you are envisioning in your head, but it has a pretty specific caveat in that it will only work if every one of your feature branch merges uses --no-ff
and creates a merge commit. So, if you always use --no-ff
(or if master
moves so quickly that you'll always need a merge commit and you don't rebase your feature branch), then you should be able to filter the branches by those who's tip commit is reachable by master
, and also if a merge commit exists on master
with that tip commit as one of it's parents. This might take a minute to script out but once you have it, you can re-use it indefinitely.