You seem to have two problems here at the same time.
Assuming a story similar to the one you described:
my_branch v ----A---B---C-------G \ \ / --*D*---E---F ^ other_branch
Why diff is not empty:
This situation is caused by the commands you specify, i.e. located on my_branch and then git merge other_branch . This action committed a merge of G and moved the current branch ( my_branch ) forward, but there was other_branch where it was. This is how merging always works! Naturally, at this point there will still be a difference between my_branch ( G ) and other_branch ( F ) - they point to different commits in the end.
If you want the two branches to be the same, you can move up other_branch following ways:
git checkout other_branch; git merge my_branch git checkout other_branch; git merge my_branch is a quick merge since G is a descendant of F- [while not on
other_branch !] git branch -D other_branch; git branch other_branch my_branch git branch -D other_branch; git branch other_branch my_branch - this will remove other_branch and then recreate it in the same place where my_branch is currently git checkout other_branch; git reset --hard my_branch git checkout other_branch; git reset --hard my_branch - this will move the other_branch to indicate exactly where my_branch is currently pointing
After doing one of these steps, both my_branch and other_branch will point to G
Why commit D changes are not in my_branch ( G )
Git brings stories together, not changes. This usually means that Git will take the two sides of the merge (and, if possible, their younger common ancestor will do, aka merge-base ) and try to combine them. Since Git takes snapshots rather than changeets / deltas / diffs, this does not contain any information about other commits or changes to the actual merge.
Using the merge base, Git performs the so-called tripartite merge, using a common ancestor to try and decisively allow changes on both sides. If he cannot, he will abort the merge and require the user to resolve the conflicts.
It is likely that something happened in your story : either commit E or F returned (or redefined) changes to D - this could happen during the merger that made E or the actual (manual) change to F
As you yourself mentioned in the commentary, you often switch between commits and editing. This way you will be swimming a lot (Git carries uncommitted changes during checks), which can make it very difficult to determine where the changes should go and where they really go. Try to avoid this, either by making any changes before changing the branches, or by using git stash to buffer them.