Scott C Wilson
Scott C Wilson

Reputation: 20016

Why does git branch --merged not show all merged branches?

I created a feature branch, then created a PR for it. My PR was accepted and merged. The PR says, "the branch can be safely deleted." But when I do git branch --merged on the main branch, I don't see the merged branch. What I am doing wrong?

Upvotes: 15

Views: 10357

Answers (4)

Dillion
Dillion

Reputation: 184

I experienced this too, and what I learnt was that the state of the remote branch before it was merged is different from the remote branch I have

Instead of using the regular merge, which adds a "merge commit", I was using the fast-forward merge approach on GitLab. And this is where the state of the branches conflicts.

If I want to fast-forward the changes introduced on testing on main, testing would need to already contain all the changes in main. But in a case where new changes may have been introduced to main since the time testing was created, a fast-forward merge cannot happen. testing does not contain ALL the changes in main.

For a fast-forward to work, I'd first need to rebase testing with main. GitLab UI has a rebase button so I don't need to do that locally.

When I rebase the testing branch on remote, before merging to main, the testing branch would now have a different state, compared to the testing branch I have locally (because I didn't also rebase locally). In fact, running git status locally, git will tell you that you have divergent branches because the histories are different.

So when the remote branch is merged to main on remote, and you pull main, and check for merged local branches, git will not be able to tell that testing has been merged:

git checkout main
git pull origin main
git branch --merged
# will not show testing

Why? Because, as I said earlier, **the state of the remote testing branch before it was merged is different from the state of the local testing branch. Though, you can check if the remote testing branch has been merged:

git branch -r --merged
# origin/testing would show

The r option shows only remote branches, and by checking the merged remote branches, you would see that the remote testing branch (maybe origin/testing) is listed.

So how do you verify if the local testing branch has been merged? For that, you have to put the local testing branch in the same state with the remote testing branch.

You can do that by rebasing locally.

You can either rebase with main

git checkout testing
git rebase main

Now, testing will contain ALL the changes in main (which was what caused the difference in states with the remote testing) and would put the local and remote branches in the same state.

Or you can rebase with the remote branch

git checkout testing
git rebase origin/testing

Same thing happens, the local testing branch would be in the same state with the remote testing branch.

Now, when you run git branch --merged locally, git can verify (because, same states) if the testing branch has indeed been merged. If origin/testing has been merged, then definitely, testing has been merged.

Note that it's possible that you did not rebase yourself, but someone working on your branch must have. The main problem here is that the state of the branches have changed and that's why git cannot verify your local branch. Something "happened" to your remote branch which didn't happen to your local branch.

I shared more detail about this in my article for further learnings :)

Upvotes: 0

Michael Freidgeim
Michael Freidgeim

Reputation: 28435

I had similar problem, when feature branches were merged to develop and develop was merged to master. Such branches are not shown for

git branch --merged master

but shown for

git branch --merged develop

But it’s better to use -r flag as recommended in How do I delete all Git branches which have been merged?

Delete remote git branches : 

git branch -r --merged | grep -v '\*\|master\|develop\|release' | sed 's/origin\///' 
| xargs -n 1 git push --delete origin

Upvotes: 0

ktsangop
ktsangop

Reputation: 1173

I have been struggling with this also. We are using gitlab's MR flow, which is probably the most simple merge based git flow.

What I have noticed is that we select to Squash Commits when a MR is merged. As a consequence this affects git history and prevents the --merged flag from working as expected.

Upvotes: 18

Ross Hunter
Ross Hunter

Reputation: 141

This is a difficult question to answer without knowing the exact workflow.

I assume since you 'created a PR' you forked/cloned a non-local repo to start with. Then you created a new branch in your local repository, made changes to add a feature, and committed those changes onto your local feature branch.

Beyond that it's a bit murkier. Here are a few steps you might take:

  1. You say you submitted a PR, but you don't say that you ever merged the feature branch with your local master branch. That suggests you may be following a workflow like this one. If that's the case, and you're running git branch --merged in your local repository, the reason you don't see your feature branch listed is that you never merged your feature branch into master in your local repository. This, IMO, is the most likely scenario. Try running git pull <name of your remote--probably origin> master from your local master branch, then trying running git branch --merged again.

  2. Fast-forwarding could cause some confusion, though it wouldn't create the issue you're describing on its own.

  3. You can always run git log on a given branch to see its full commit history. You could examine the commit history of your master and compare it to the commit history of origin/master to maybe find the discrepancy.

Hope this helps!

Upvotes: 2

Related Questions