I have a git repository with multiple branches.
How can I know which branches are already merged into the master branch?
11 Answers
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.
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.
In order to verify which branches are merged into master you should use these commands:
git branch <flag[-r/-a/none]> --merged masterlist of all branches merged into master.git branch <flag[-r/-a/none]> --merged master | wc -lcount number of all branches merged into master.
Flags Are:
-aflag - (all) showing remote and local branches-rflag - (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.
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
2I 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 } 3Use 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
- Find last commit hash on master branch
- Find last commit hash on a "branch"
- Run command
git merge-base <commit-hash-step1> <commit-hash-step2>. - If output of step 3 is same as output of step 2, then a "branch" has been already merged into master.
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
1I 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)
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" } 6Here 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.
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"