Home > Mobile >  How does GitHub produce this diff?
How does GitHub produce this diff?

Time:02-17

Here's the diff in question. It's a view of 2/3 commits for a Pull Request: GitHub diff

However if I do a naive git diff at the command line I get something else:

git diff 5b7549cd97845c41019478f8f339a90c0256014f..7327dfcfb3a95b31f8bf4845556196abe33fefc8
diff --git a/index.js b/index.js
index 5f87902..1885a31 100644
--- a/index.js
    b/index.js
@@ -5,6  5,10 @@ function main(args) {
   console.info(args);
 }

 function qooBoz() {
   console.log("qooBoz");
 }
 
 function fooBar(x, y) {
   const z = x   y;
   return z;
@@ -16,6  20,7 @@ function barBaz(q, z) {
 }

 function bizBom(a, b) {
   console.log("bizBom");
   const c = a   b;
   return c;
 }

The difference is that GitHub seems to be "ignoring" the merge commit and just focusing on the changes made by the PR author. In most cases that's the relevant diff and what I'd ike to see.

How can I get that same diff at the command line, knowing only the two commit hashes 5b7549cd97845c41019478f8f339a90c0256014f and 7327dfcfb3a95b31f8bf4845556196abe33fefc8?


Edit 1

I think a clearer way to ask is: what is the difference between what GitHub is doing, in terms of git operations, at these two links:

GitHub diff

GitHub diff

CodePudding user response:

This becomes much clearer when you look at the graph:

$ git log --graph --oneline
* 7327dfc (HEAD -> add-biz-bom, origin/add-biz- bom) Add logging
*   fab1ea5 Merge branch 'main' into add-biz-bom
|\
| * 0d8e5b1 (origin/main, origin/HEAD, main) Add qooBoz function
* | 5b7549c Add bizBom function
|/
* 2e178d9 Add more to index.js
* a9fdc92 Update index.js
...

The reason GitHub is "ignoring" the merge commit (fab1ea5) is because:

  1. The merge commit itself has no changes (this is typical).
  2. The commit that the merge brings in is 0d8e5b1 which is already in main, so from the point of view of this PR that commit will not be added to main when the PR is completed.

The view you linked to is only diffing 2 commits; one is the merge commit with no changes, and the other is commit 7327dfcf which by itself just adds the one line console log you see in the screenshot. If you want to see that from the command line you could use:

git diff fab1ea5..7327dfc

or if you didn't "know" what the commit ID of the merge commit was, you could use:

git diff 7327dfc~1..7327dfc

Side Note: If you're interested in seeing the diff for all 3 commits in the context of this PR, to mimic that set of changes you could use:

git diff 0d8e5b1...7327dfc

or perhaps more intuitively:

git diff origin/main...origin/add-biz-bom

Note for most of the above commands you could use either 2 dots (..) or 3 dots (...) and you'd get the same answer in this case. But for the last one using the branch names in the context of a PR, you should always use 3 dots, since origin/main could be ahead of the merge-base of your PR. See this answer for a quick cheat sheet on the differences between 2 and 3 dots.

Caveat: Even the last diff command of the two branches is an over-simplification. If some changes were added to both the source and target branches of a PR (say, due to cherry-picking or duplicated efforts by different people), then the actual diff in the context of the PR could be a subset of the output of that last command.

  • Related