330

I have a Git repository with many branches, some of them already merged and some not. Since the number of branches is quite large, how can I determine which branches have not yet been merged? I would like to avoid having to do an "octopus" merge and re-merging branches that have already been merged.

DavidRR
  • 18,291
  • 25
  • 109
  • 191
fluca1978
  • 3,968
  • 2
  • 15
  • 15
  • 6
    First I was laughing about the term of the "octopus merge". But in case you didn't know, like me: That's the official name of a merge strategy :-) See https://git-scm.com/docs/git-merge or https://www.atlassian.com/de/git/tutorials/using-branches/merge-strategy – observer Apr 02 '20 at 08:50

4 Answers4

553

Try this:

git branch --merged master

It does what it says on the tin (lists branches which have been merged into master). You can also pull up the inverse with:

git branch --no-merged master

If you don't specify master, e.g...

git branch --merged

then it will show you branches which have been merged into the current HEAD (so if you're on master, it's equivalent to the first command; if you're on foo, it's equivalent to git branch --merged foo).

You can also compare upstream branches by specifying the -r flag and a ref to check against, which can be local or remote:

git branch -r --no-merged origin/master
Amber
  • 507,862
  • 82
  • 626
  • 550
  • 6
    If you merge `foo` into `master`, it will appear in the `git branch --merged master` list. But what happens if you commit once more to `foo`? Does it no longer appear in that list, or does it, as even though it has new commits, it was *at one point* merged into `master`? – Craig Otis Jul 09 '13 at 14:13
  • 12
    @CraigOtis It will no longer appear in the list. `--merged` only lists branches that are *completely* merged into the given branch. – Amber Jul 09 '13 at 17:00
  • and `gitk --remotes --not origin/master` will show you the commits on each branch that have not been merged to master. – yoyo Jun 21 '16 at 16:18
  • 8
    Imagine this... a git answer that's easy to understand and use! – jleach Nov 03 '17 at 09:41
  • 2
    Is there a way to get the list without checking out the branch? Like pointing to the server and then get the list? – xbmono Oct 21 '19 at 00:41
  • 2
    As I found, the `git branch --no-merged master` shows only my local branches. It doesn't show any branch that was not checked out on my computer and created by someone else. – Anton Danilchenko Feb 26 '20 at 11:31
  • 1
    @AntonDanilchenko which is exactly as you'd expect. If you wanted to see remote branches as well use the `--all` flag. – mfurseman Aug 04 '22 at 06:38
  • Does this correctly find branches that have been **squash merged** into the target branch? Frequently squashes throw off tools that need direct paths between branches to work correctly, `gitversion` for example. – Max Cascone Aug 24 '22 at 16:19
80

You can also use the -r parameter to show remote branches that were not merged into master:

git branch -r --merged master

git branch -r --no-merged

                         
observer
  • 2,925
  • 1
  • 19
  • 38
NemoXP
  • 896
  • 6
  • 5
31

If a branch is merged already, merging it again won't do anything. So you don't have to be worried about "re-merging" branches that are already merged.

To answer your question, you can simply issue

 git branch --merged

to see the merged branches or

 git branch --no-merged

to see the unmerged branches. Your current branch is implied but you can specify other branches if you wish.

 git branch --no-merged integration

will show you branches that are not yet merged into integration branch.

Adam Dymitruk
  • 124,556
  • 26
  • 146
  • 141
1

The below script will find all origin/* branches that are ahead of current branch

#!/bin/bash

CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)

echo -e "Current branch: \e[94m$CURRENT_BRANCH\e[0m"
echo ''

git branch -a | grep remotes/origin/ | while read LINE
do
    CMD="git diff --shortstat remotes/origin/${CURRENT_BRANCH}...${LINE}"

    if $CMD | grep ' file' > /dev/null; then
        echo -e "\e[93m$LINE\e[0m" | sed 's/remotes\/origin\///'
        $CMD
        echo ''
    fi
done
moldcraft
  • 438
  • 7
  • 21