1443

I have a git repository with multiple branches.

How can I know which branches are already merged into the master branch?

Mus
  • 7,290
  • 24
  • 86
  • 130
hectorsq
  • 74,396
  • 19
  • 43
  • 46

12 Answers12

2229

git branch --merged master lists branches merged into master

git branch --merged lists branches merged into HEAD (i.e. tip of current branch)

git branch --no-merged lists branches that have not been merged

By default this applies to only the local branches. The -a flag will show both local and remote branches, and the -r flag shows only the remote branches.

Jake Berger
  • 5,237
  • 1
  • 28
  • 22
hectorsq
  • 74,396
  • 19
  • 43
  • 46
  • 2
    Just a side note, when I tried to see if a remote branch had been merged I first setup a local tracking branch, identified the status with `git branch --merged` and then deleted the local and remote branches. – Kenneth Kalmer Jul 01 '11 at 08:30
  • 103
    Apparently, `git branch -a --merged/no-merged` does also work, without creating a local tracking branch in the process. – fresskoma Jul 23 '11 at 11:17
  • 89
    Or just `git branch -r --merged/--no-merged` to only find remote branches. – Asfand Qazi Aug 24 '12 at 11:07
  • 10
    Any way to delete unmerged branches which were actually merged after rebasing? – Ashfame Feb 22 '14 at 03:52
  • 1
    @Ashfame: I don't think so, rebasing creates entirely new commits. I have the same problem moving between two computers. I need to clean up twice and also remember what branches I did merge on either computer, since I always rebase feature branches before I merge it into our team's develop branch. One technique I've found helpful is to always delete the remote branch immediately after merging it, so I can just 'git branch -r' on either computer to see what feature branches I have on-going. – angularsen May 13 '14 at 06:17
  • @AndreasLarsen Yeah close to what I deal with. Wish there was a way to do it. – Ashfame May 13 '14 at 12:33
  • @Ashfame: I've recently started using post-flow-feature-finish git hook to ask me if I want to auto-remove the remote branch every time I complete a feature branch. This is very helpful to remember cleaning up the remote. This requires [git flow extensions (AVH edition)](https://github.com/petervanderdoes/gitflow), but I'm sure you can get something similar working with plain git hooks. – angularsen May 29 '14 at 08:09
  • 11
    Note that `--merged/--no-merged` takes an optional commit argument after it. At least in my version of git (1.9.1), adding the `-a` or `-r` flag after it give me a fatal error. Add the `-a` or `-r` _before_ `--(no-)merged`. – jgawrych Feb 10 '15 at 17:00
  • how would you carry out this operation ie git branch -r --merged without having previously cloned the repo locally ie is there a way to issue a command like branch -r --merged ? – diarmuid Oct 19 '17 at 13:59
  • 1
    Is this still correct? I get `fatal: malformed object name master` – John Hascall Jul 07 '18 at 17:01
  • Is there any way to restrict this to branches merged after a particular commit? e.g. `git branch -r --merged origin/develop..origin/master` – Travis Clarke Nov 13 '18 at 07:37
  • If you have multiple remotes, is there a way to limit this query to just one of them? – Ian Jan 04 '19 at 13:10
  • anyone else also getting wrong results when the remote is hosted on gitlab? a said branch was merged but still shows up in no-merge – Yash Kumar Verma Jun 18 '22 at 18:52
  • I'm not getting the correct results at all with these options. For example, I have `release/*` branches that I not are NEVER merged to `master` but they show up in the `git branch -r --merged origin/master` command – Chris F Jul 15 '22 at 19:50
  • Is it possible to ignore the current branch so that we can `git branch --merged | xargs git branch -d` to delete all unmerged branches? – luochen1990 Aug 17 '22 at 09:28
  • Does anyone know if `git branch -r --merged master` will also show branches that have been merged to master, but had commits afterwards to it that weren't merged yet? – nl-x Jul 07 '23 at 08:35
148

You can use the git merge-base command to find the latest common commit between the two branches. If that commit is the same as your branch head, then the branch has been completely merged.

Note that git branch -d does this sort of thing already because it will refuse to delete a branch that hasn't already been completely merged.

Palec
  • 12,743
  • 8
  • 69
  • 138
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
48

In order to verify which branches are merged into master you should use these commands:

  • git branch <flag[-r/-a/none]> --merged master list of all branches merged into master.
  • git branch <flag[-r/-a/none]> --merged master | wc -l count number of all branches merged into master.

Flags Are:

  • -a flag - (all) showing remote and local branches
  • -r flag - (remote) showing remote branches only
  • <emptyFlag> - showing local branches only

for example: git branch -r --merged master will show you all remote repositories merged into master.

avivamg
  • 12,197
  • 3
  • 67
  • 61
  • `git branch -r merged main` will show you branches that you "deleted" on GitHub because [GitHub keeps a record of recently deleted PR branches](https://docs.github.com/en/github/administering-a-repository/managing-branches-in-your-repository/deleting-and-restoring-branches-in-a-pull-request) – Chuan Sep 09 '21 at 02:04
  • How do you interpret the output? When I do `git branch --merged master` it dumps "master". But if I do the same for my develop branch, it lists some feature branches and develop and master. – Ken Hadden Dec 16 '22 at 21:36
38

There is a graphical interface solution as well. Just type

gitk --all

A new application window will prompt with a graphical representation of your whole repo, where it is very easy to realize if a branch was already merged or not

iberbeu
  • 15,295
  • 5
  • 27
  • 48
  • 24
    Which to be clear, requires the installation of an application that is not part of the `git` client. On Ubuntu, `apt-get install gitk`. – metame Apr 27 '17 at 12:36
  • 3
    On macOS, if you have Homebrew installed, would be `brew install git-gui`, to get `gitk` on the commandline. – program247365 Apr 29 '20 at 18:27
33

Use git merge-base <commit> <commit>.

This command finds best common ancestor(s) between two commits. And if the common ancestor is identical to the last commit of a "branch" ,then we can safely assume that that a "branch" has been already merged into the master.

Here are the steps

  1. Find last commit hash on master branch
  2. Find last commit hash on a "branch"
  3. Run command git merge-base <commit-hash-step1> <commit-hash-step2>.
  4. If output of step 3 is same as output of step 2, then a "branch" has been already merged into master.

More info on git merge-base https://git-scm.com/docs/git-merge-base.

Hari
  • 631
  • 7
  • 5
  • 2
    I think this will only tell you if the tips are merged. For example, this won't tell you if `master` was merged into `branch`, and then 4 more commits were added into `branch`. – mkobit Feb 26 '18 at 20:42
  • Why not `git log -1 $(git merge-base base-branch feature-branch)` and if you see `feature-branch` in the output, then you know they are merged? – Carl G Mar 22 '18 at 16:39
32

I am using the following bash function like: git-is-merged develop feature/new-feature

git-is-merged () {
  merge_destination_branch=$1
  merge_source_branch=$2

  merge_base=$(git merge-base $merge_destination_branch $merge_source_branch)
  merge_source_current_commit=$(git rev-parse $merge_source_branch)
  if [[ $merge_base = $merge_source_current_commit ]]
  then
    echo $merge_source_branch is merged into $merge_destination_branch
    return 0
  else
    echo $merge_source_branch is not merged into $merge_destination_branch
    return 1
  fi
}
Carl G
  • 17,394
  • 14
  • 91
  • 115
  • 5
    this actually doesn't work. If the source branch has been merged into the destination branch already, and then destination branch gets a few more commits, it doesn't work anymore but I don't know why – Alexander Mills Jul 16 '18 at 05:44
  • 1
    see the question here: https://stackoverflow.com/questions/51355331/checking-if-branch-has-already-been-merged-into-master-or-dev-branches-on-remote – Alexander Mills Jul 16 '18 at 05:53
  • 1
    @AlexanderMills It works fine for me even if the destination branch gets a few more commits after merging the source branch – Grodriguez Aug 11 '21 at 14:45
20

On the topic of cleaning up remote branches

git branch -r | xargs -t -n 1 git branch -r --contains

This lists each remote branch followed by which remote branches their latest SHAs are within.

This is useful to discern which remote branches have been merged but not deleted, and which haven't been merged and thus are decaying.

If you're using 'tig' (its like gitk but terminal based) then you can

tig origin/feature/someones-decaying-feature

to see a branch's commit history without having to git checkout

xxjjnn
  • 14,591
  • 19
  • 61
  • 94
  • 3
    Well done that man! Very useful once you get your head around what it's actually displaying! The GitHub app needs to incorporate this into a visual display of your branches, rather than an alphabetised list with no hierarchy! – CMash Mar 03 '15 at 09:04
  • So this command shows branches that have been merged to `origin/master` but NOT deleted remotely? – Chris F Jul 15 '22 at 19:52
  • I think so... you might need to run `git remote prune origin` to update your local machine on what is and is not deleted – xxjjnn Jul 18 '22 at 11:05
14

I use git for-each-ref to get a list of branches that are either merged or not merged into a given remote branch (e.g. origin/integration)

Iterate over all refs that match <pattern> and show them according to the given <format>, after sorting them according to the given set of <key>.

Note: replace origin/integration with integration if you tend to use git pull as opposed to git fetch.

List of local branches merged into the remote origin/integration branch

git for-each-ref --merged=origin/integration --format="%(refname:short)" refs/heads/
#                ^                           ^                           ^
#                A                           B                           C
branch1
branch2
branch3
branch4

A: Take only the branches merged into the remote origin/integration branch
B: Print the branch name
C: Only look at heads refs (i.e. branches)

List of local branches NOT merged into the remote origin/integration branch

git for-each-ref --no-merged=origin/integration --format="%(committerdate:short) %(refname:short)" --sort=committerdate refs/heads
#                ^                              ^                                                  ^                    ^
#                A                              B                                                  C                    D
2020-01-14 branch10
2020-01-16 branch11
2020-01-17 branch12
2020-01-30 branch13

A: Take only the branches NOT merged into the remote origin/integration branch
B: Print the branch name along with the last commit date
C: Sort output by commit date
D: Only look at heads refs (i.e. branches)

customcommander
  • 17,580
  • 5
  • 58
  • 84
  • This command is not working for me -- List of local branches NOT merged into the remote origin/integration branch – Rahul Vyas Feb 25 '22 at 07:48
9

To check whether a source branch has been merged into the master branch, the following bash command can be used:

git merge-base --is-ancestor <source branch name> master && echo "merged" || echo "not merged"
Harish Ambady
  • 12,525
  • 4
  • 29
  • 54
6

Here are my techniques when I need to figure out if a branch has been merged, even if it may have been rebased to be up to date with our main branch, which is a common scenario for feature branches.

Neither of these approaches are fool proof, but I've found them useful many times.

1 Show log for all branches

Using a visual tool like gitk or TortoiseGit, or simply git log with --all, go through the history to see all the merges to the main branch. You should be able to spot if this particular feature branch has been merged or not.

2 Always remove remote branch when merging in a feature branch

If you have a good habit of always removing both the local and the remote branch when you merge in a feature branch, then you can simply update and prune remotes on your other computer and the feature branches will disappear.

To help remember doing this, I'm already using git flow extensions (AVH edition) to create and merge my feature branches locally, so I added the following git flow hook to ask me if I also want to auto-remove the remote branch.

Example create/finish feature branch

554 Andreas:MyRepo(develop)$ git flow start tmp
Switched to a new branch 'feature/tmp'

Summary of actions:
- A new branch 'feature/tmp' was created, based on 'develop'
- You are now on branch 'feature/tmp'

Now, start committing on your feature. When done, use:

     git flow feature finish tmp

555 Andreas:MyRepo(feature/tmp)$ git flow finish
Switched to branch 'develop'
Your branch is up-to-date with 'if/develop'.
Already up-to-date.

[post-flow-feature-finish] Delete remote branch? (Y/n)
Deleting remote branch: origin/feature/tmp.

Deleted branch feature/tmp (was 02a3356).

Summary of actions:
- The feature branch 'feature/tmp' was merged into 'develop'
- Feature branch 'feature/tmp' has been locally deleted
- You are now on branch 'develop'

556 Andreas:ScDesktop (develop)$

.git/hooks/post-flow-feature-finish

NAME=$1
ORIGIN=$2
BRANCH=$3

# Delete remote branch
# Allows us to read user input below, assigns stdin to keyboard
exec < /dev/tty

while true; do
  read -p "[post-flow-feature-finish] Delete remote branch? (Y/n) " yn
  if [ "$yn" = "" ]; then
    yn='Y'    
  fi
  case $yn in
      [Yy] ) 
        echo -e "\e[31mDeleting remote branch: $2/$3.\e[0m" || exit "$?"
        git push $2 :$3; 
        break;;
      [Nn] ) 
        echo -e "\e[32mKeeping remote branch.\e[0m" || exit "$?"
        break;;
      * ) echo "Please answer y or n for yes or no.";;
  esac
done

# Stop reading user input (close STDIN)
exec <&-
exit 0

3 Search by commit message

If you do not always remove the remote branch, you can still search for similar commits to determine if the branch has been merged or not. The pitfall here is if the remote branch has been rebased to the unrecognizable, such as squashing commits or changing commit messages.

  • Fetch and prune all remotes
  • Find message of last commit on feature branch
  • See if a commit with same message can be found on master branch

Example commands on master branch:

gru                   
gls origin/feature/foo
glf "my message"

In my bash .profile config

alias gru='git remote update -p'
alias glf=findCommitByMessage

findCommitByMessage() {
    git log -i --grep="$1"
}
angularsen
  • 8,160
  • 1
  • 69
  • 83
  • @anjdeas - step 1 - how do you know which branches have been merged into main. I've been looking at the logs and gui tools - and cannot find anywhere where it explicitly shows this??? – The Huff Sep 15 '15 at 22:39
  • @TheHuff Try this: `git log --all --color --graph --decorate --topo-order --date=relative --abbrev-commit --pretty=format:"%C(green)%h %C(red bold)[%<(14)%ad] %Creset%s%Cred%d%C(blue) [%an]"` – angularsen Sep 15 '15 at 22:50
  • @TheHuff In TortoiseGit, if you are on the main branch, it should show all merges into main. – angularsen Sep 15 '15 at 22:52
  • Thanks - but how do I know what is a merge? I'm assuming they are all commits - is this right? – The Huff Sep 16 '15 at 01:38
  • @TheHuff: You should visually see two streams/paths of commits merge together to a single commit "downstream" (higher up in log view). That commit is a merge commit. Also, in `git log` you can add `--merges` to only show merge commits. http://stackoverflow.com/a/25986615/134761 – angularsen Sep 16 '15 at 07:26
  • I like the `git log -i --grep=""` method as that seems to work well for branches that were rebased onto main as well (as long as the commit you are looking for was not squashed together). Using that I can easily check the commit author and date that comes out of that query on my main branch against the log of my minor branch. – TafT Dec 17 '15 at 10:37
6

Here is a little one-liner that will let you know if your current branch incorporates or is out of data from a remote origin/master branch:

$ git fetch && git branch -r --merged | grep -q origin/master && echo Incorporates origin/master || echo Out of date from origin/master

I came across this question when working on a feature branch and frequently wanting to make sure that I have the most recent work incorporated into my own separate working branch.

To generalize this test I have added the following alias to my ~/.gitconfig:

[alias]
   current = !git branch -r --merged | grep -q $1 && echo Incorporates $1 || echo Out of date from $1 && :

Then I can call:

$ git current origin/master

to check if I am current.

radke
  • 556
  • 7
  • 7
0

I diff the git branch against git branch --merged main as follows:

diff <(git branch) <(git branch --merged main)

Then you'll see any local branches that haven't been merged into main.

cjohnson318
  • 3,154
  • 30
  • 33