How can I know if a branch has been already merged into master?
Asked Answered
W

13

1467

I have a git repository with multiple branches.

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

Wellgrounded answered 22/10, 2008 at 18:23 Comment(0)
W
2263

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.

Wellgrounded answered 22/10, 2008 at 18:33 Comment(16)
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.Africanist
Apparently, git branch -a --merged/no-merged does also work, without creating a local tracking branch in the process.Endorsement
Or just git branch -r --merged/--no-merged to only find remote branches.Camembert
Any way to delete unmerged branches which were actually merged after rebasing?Coly
@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.Jeanejeanelle
@AndreasLarsen Yeah close to what I deal with. Wish there was a way to do it.Coly
@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), but I'm sure you can get something similar working with plain git hooks.Jeanejeanelle
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.Dished
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 <git-command> <credentials> branch -r --merged <repositorUrl> ?Fiorenze
Is this still correct? I get fatal: malformed object name masterChantel
Is there any way to restrict this to branches merged after a particular commit? e.g. git branch -r --merged origin/develop..origin/masterUpanddown
If you have multiple remotes, is there a way to limit this query to just one of them?Severe
anyone else also getting wrong results when the remote is hosted on gitlab? a said branch was merged but still shows up in no-mergeAccusative
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 commandBloomers
Is it possible to ignore the current branch so that we can git branch --merged | xargs git branch -d to delete all unmerged branches?Cerography
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?Halberd
G
150

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.

Gasometry answered 22/10, 2008 at 18:25 Comment(8)
@hari's answer goes into more detail on how to use this.Delly
how can we do this automatically/programmatically?Cataclinal
"hasn't already been completely merged" ... completely merged into what branch?Cataclinal
@AlexanderMills: Into your current branch.Gasometry
you can't delete your current branch, so it would never work? that makes no senseCataclinal
@AlexanderMills: git branch -d will refuse to delete a branch that has not been merged into the current branch. Not deleting the current branch.Gasometry
merge-base is surely the right technique, and @Carl G's answer should work, but for some reaoson it's not working. See the question here: stackoverflow.com/questions/51355331/…Cataclinal
git branch -d . I'm running command FROM the branch that it's fully committed to, but it's still saying it's not full committed.Crat
S
51

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.

Sw answered 22/7, 2019 at 13:12 Comment(2)
git branch -r merged main will show you branches that you "deleted" on GitHub because GitHub keeps a record of recently deleted PR branchesSpermatic
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.Just
H
39

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

Horwath answered 23/10, 2013 at 10:19 Comment(2)
Which to be clear, requires the installation of an application that is not part of the git client. On Ubuntu, apt-get install gitk.Intrastate
On macOS, if you have Homebrew installed, would be brew install git-gui, to get gitk on the commandline.Jury
P
34

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.

Publishing answered 13/10, 2016 at 2:5 Comment(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.Diffractometer
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?Dust
D
33

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
}
Dust answered 22/3, 2018 at 16:49 Comment(3)
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 whyCataclinal
see the question here: stackoverflow.com/questions/51355331/…Cataclinal
@AlexanderMills It works fine for me even if the destination branch gets a few more commits after merging the source branchEchelon
P
21

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

Pygmy answered 23/10, 2013 at 10:9 Comment(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!Rosiarosicrucian
So this command shows branches that have been merged to origin/master but NOT deleted remotely?Bloomers
I think so... you might need to run git remote prune origin to update your local machine on what is and is not deletedPygmy
G
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)

Gillie answered 17/11, 2020 at 16:53 Comment(1)
This command is not working for me -- List of local branches NOT merged into the remote origin/integration branchSeizing
G
10

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"
Guarneri answered 17/12, 2021 at 6:43 Comment(0)
J
7

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"
}
Jeanejeanelle answered 29/5, 2014 at 8:45 Comment(6)
@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???Pampero
@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]"Jeanejeanelle
@TheHuff In TortoiseGit, if you are on the main branch, it should show all merges into main.Jeanejeanelle
Thanks - but how do I know what is a merge? I'm assuming they are all commits - is this right?Pampero
@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. https://mcmap.net/q/12782/-how-to-do-git-log-see-only-merges-to-master-branchJeanejeanelle
I like the git log -i --grep="<summary>" 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.Theater
F
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.

Forest answered 15/11, 2018 at 18:22 Comment(0)
A
2

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.

Airdrome answered 13/10, 2022 at 2:49 Comment(0)
R
1

You can't use git branch --merged to check a branch that was merged with a squash commit for the reasons stated above.

However, if you merged the branch through a GitHub Pull Request, you can use the gh utility to set-difference your branches with branches whose pull requests were "merged" into your base ref:

diff <(git branch -l | grep -Ev '(main|master)') <(gh pr list --state closed | awk -F '\t' '{print $3}') | grep -E '^>' | awk '{print $NF}'
Ricebird answered 5/12, 2023 at 20:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.