GitHub pull requests showing invalid diff for already merged branch

We’re seeing an issue with how pull requests are performed by GitHub. When we model a pull request after previously merging a change from one branch into another, it’s previewing the same “diff” as before, even though we can show the previous change was indeed already made to the branch. GitHub seems to get into this infinite loop of trying to reapply the same change as already merged each time we model the pull request, regardless of how many times we try to merge it. And when each such pull request is actually merged, git in fact does the right thing: nothing! The supposed merge commit will show “0 Changed files with 0 additions and 0 deletions”. Why is GitHub lying to us about what the differences are between our 2 branches?

37 Likes

That seems like a bug. You might want to report that here: https://github.com/contact.

2 Likes

Yes, I agree. GitHub seems to think this is a design feature, however. Their response when I posted via that form, below. From my persepctive though it’s still giving an incorrect answer. It’s showing a difference when there actually isn’t one, and then offering to do a merge assuming that difference, which ultimately results in a no-op because there actually isn’t one. Definitely feels like a bug to me too!

From GitHub: 

"When you merge commits from a Pull Request into a branch, the commit SHA changes from what the original commit SHA’s were.

This means when you compare the same two branches again, the diff will show those commits again because those specific commit SHA’s don’t exist on the branch you’re merging into.

This is a result of the type of diff we use on GitHub. We use git’s three dot diff, which is the difference between the latest commit on the HEAD branch and the last common ancestor commit with the base branch.

This workflow is designed for a topic branch model. The presumption with the topic branch flow is that a branch is created to merge in a specific feature. Once the branch has been merged it would be deleted and further development would be made on a new branch.

A lot of teams use a master > dev branch model though and for this, once a Pull Request is merged, the master branch would be merged back onto dev using the command line:

git checkout devgit rebase master Rebasing the master back onto dev updates dev with the latest commits from master and should give you a clean diff again.!"

29 Likes

great explaination for the github diff mechanism!

2 Likes

Just checked this locally by:

  1. creating a repo with 1 file and committing it to commit “A”, in master

  2. Checkout to a new branch called “mybranch” and do a git reset head~1

  3. Make a new commit to commit “B” with the exact same content as “A”

  4. git diff master (on mybranch) gives no results, as expected. 

3 Likes

Apologies for resurrecting an old thread, but wouldn’t rebasing master back onto dev change the history of dev, and make it necessary for team members working off dev to take recovery measures?  

4 Likes

We recently experienced this issue. Git hub shows an incorrect diff on a bug fix to a minor release. Using git diff between the tags on the command line showed the correct diff.

4 Likes

@[kirkwatrous] GitHub’s explanation for 2 years ago actually explains it in terms of SHA numbers, although I can’t say I agree with the concept.

The word diff is literal and there’s nothing “implied” in it regarding what is the diff it should be showing.

Squashed merges already have all the content of the topic branch that previously had a PR. That means that computing a diff that the same content again (albeit having a different SHA) is incorrect by the definition of the word “difference”.

2 Likes

When this can be fixed ?
To see the difference that doesn’t really exist is really anonying. It’s not a feature.

6 Likes

If you want to make this a “feature,” then you should provide the option for how the diff is calculated and displayed. When I perform a diff, I want to see the actual diff between the files in the branches. I could care less about the different SHA values. I would bet 95% if GitHub users would agree with me…

14 Likes

This appears to be fixed in Github, but not well documented. From the earlier post by kirkwatrous, the key is that Github is (by default) performing a “three-dot” diff, which seems confusing. But Github does support the “two-dot” diff, which is what seems more intuitive. To get the two-dot diff, edit the url of your repository’s “Comparing changes” page. (reference). Note that the example uses seven character SHA codes, but it works equally well with branch names. In short, just remove one dot on the “Comparing changes” url, from three dots down to two dots

10 Likes

Thanks @bradflood. You saved my day.
I think At least Github should provide a switch for users to use “three-dot” to compare or “two-dot”

6 Likes

I don’t have any dots in my pull request url. This issue always scares the developers every time it comes up. It sure would be nice if github at least offered a setting to see true file diffs in pull request files changed.

3 Likes

It’s been a while, but seriously it’s really annoying, when using rebase I always come across weird diff where previous merged commits appear as changes.

It’s hilarious, using the compare feature it shows me 10 changed files, but in the PR view I have 14 :man_facepalming: too bad I can’t upload screenshot here.

Never came across this kind of issue with gitlab, bitbucket or azure devops.

Yeah, this needs to be fixed for PRs - they need to automatically update diffs when the target branch is updated with commits that are also part of the PR (such as when other PRs are pushed that share commits).

+1. the current way of diffing just made our workflow with incremental PRs really hard.

1 Like

Git’s three-dot diff is great for merge based workflows, if you know that’s what’s going on, and you expect it. The biggest problem IMO is that the UI severely violates the principle of least surprise.

When I ask to compare two refs, I expect to see a comparison of the two refs I asked to compare. Github does not do that.

Using three-dot diff silently and implicitly when you ask to compare to branches is a horrible UX misadventure. And yes, I say “silently,” because the tooltip on the “<-” between the two refs that can be hovered over to say “using three-dot diff” does not count as making the behaviour visible, and it sure doesn’t show you the actual left ref being used in the diff.

Please consider adjusting the UI to:

  • Clearly show that the “base” ref is not the actual left side of the diff, and prominently display the actual base ref that was selected as the merge-base
  • Mention how many commits the left ref is behind the actual base ref specified by the user, and link to the compare page between the merge-base and the left HEAD so the user can easily see what is being ignored in the comparison
  • Offer a simple way to switch to “two dot” direct diff between two refs when viewing a “three dot” compare

Having to edit the URL to get the same diff that “git diff” will produce by default is bewildering.

This is extra surprising for users because “git diff” implicitly defaults to two-dot diff in the common case of diffing the current worktree’s HEAD against a single specified other ref - git checkout foo; git diff bar is equivalent to git diff foo..bar.

If the user asks github to compare branches “foo” and “bar” they do not expect to see the output of

git diff $(git merge-base foo bar)..bar