It's possible to get list of changed files between two commits. Something like that comparison between two commits in web version but using GitHub Api.
-
If you need to do this in GitHub - [check this](https://stackoverflow.com/a/49838096/820410) – Pankaj Singhal Oct 06 '20 at 16:59
-
1Does this answer your question? [How to compare two different commits on the same branch in github?](https://stackoverflow.com/questions/49837769/how-to-compare-two-different-commits-on-the-same-branch-in-github) – Neo Tan Apr 19 '23 at 13:24
-
I'm voting to close this as unclear/needs clarity, because it does not ask a question. – TylerH Apr 20 '23 at 15:23
4 Answers
The official commit comparison API is Compare two commits:
GET /repos/:owner/:repo/compare/:base...:head
Both
:base
and:head
can be either branch names in :repo or branch names in other repositories in the same network as:repo
. For the latter case, use the formatuser:branch
:
GET /repos/:owner/:repo/compare/user1:branchname...user2:branchname
Note that you can use tags or commit SHAs as well. For instance:
https://api.github.com/repos/git/git/compare/v2.2.0-rc1...v2.2.0-rc2
Note the '...
', not '..
' between the two tags.
And you need to have the oldest tag first, then the newer tag.
That gives a status:
"status": "behind",
"ahead_by": 1,
"behind_by": 2,
"total_commits": 1,
And for each commit, information about the files:
"files": [
{
"sha": "bbcd538c8e72b8c175046e27cc8f907076331401",
"filename": "file1.txt",
"status": "added",
"additions": 103,
"deletions": 21,
"changes": 124,
"blob_url": "https://github.com/octocat/Hello-World/blob/6dcb09b5b57875f334f61aebed695e2e4193db5e/file1.txt",
"raw_url": "https://github.com/octocat/Hello-World/raw/6dcb09b5b57875f334f61aebed695e2e4193db5e/file1.txt",
"contents_url": "https://api.github.com/repos/octocat/Hello-World/contents/file1.txt?ref=6dcb09b5b57875f334f61aebed695e2e4193db5e",
"patch": "@@ -132,7 +132,7 @@ module Test @@ -1000,7 +1000,7 @@ module Test"
}
]
BUT:
The response will include a comparison of up to 250 commits. If you are working with a larger commit range, you can use the Commit List API to enumerate all commits in the range.
For comparisons with extremely large diffs, you may receive an error response indicating that the diff took too long to generate. You can typically resolve this error by using a smaller commit range.
Notes:
"same network" means: two repositories hosted by the same Git repository hosting services (two repositories on github.com for example, or on the same on-premise GHE -- GitHub Enterprise -- instance)
You can therefore compare two branches between a repo and its fork.
Example:
https://api.github.com/repos/030/learn-go-with-tests/compare/master...quii:master
(this example compares a fork to its original repo, not the original repo to the fork: that is because the fork, in this case, is behind the original repo)
As noted by Tom Carver in the comments:
this suggested API silently maxes out at 300 files shown;
I haven't yet found an API that avoids this limitation

- 1,262,500
- 529
- 4,410
- 5,250
-
8I know that, but :base and :head can are branch names, but i don't want compare 2 branches heads. I want compare 2 specific commits as web example which i gave. – Unlink Nov 16 '14 at 21:36
-
@Unlink then the API doesn't provide that. What you can try is creating branches on those commits, but that would still compare all commits between the two (you might isolate your two commits though) – VonC Nov 16 '14 at 21:37
-
-
Tag or branch, the result would be the same: all commits between the two would be part of the comparison. – VonC Nov 16 '14 at 21:56
-
But it not working, when i use https://api.github.com/repos/user/repo/compare/1.0..1.1 i get only Not Found – Unlink Nov 17 '14 at 07:02
-
3@Unlink it does work. For example: https://api.github.com/repos/git/git/compare/v2.2.0-rc1...v2.2.0-rc2. Note that I used '`...`', not '`..`' between the two tags. And you need to have the oldest tag first, then the newer tag. – VonC Nov 17 '14 at 07:31
-
I just tried comparing two specific commits with the SHAs and it worked! Looks like the docs are just out of date, I will try to find a place to let Github know – Arie Milner May 30 '19 at 00:49
-
From a successful `compare`, I do not get the JSON response shown above. I get a base64 response: `{"$content-type": "application/vnd.github.v3.diff; charset=utf-8","$content": "RnJvbSBmYmUxYWJmM2U3MDR...}`. What file extension do I put on the converted base64-to-binary in order to view it? – SeaDude Jan 13 '20 at 05:01
-
@SeaDude Strange, it might have changed since 2014 (when I wrote the answer). I don't see a base64 answer to https://api.github.com/repos/git/git/compare/v2.2.0-rc1...v2.2.0-rc2 though. – VonC Jan 13 '20 at 05:03
-
All good; I'm using an uncommon tool (Power Automate) to make the API call. Converted the base64 to binary and slapped a `.diff` or `.patch` respectively and was able to see the content. https://postimg.cc/k2SwwpQf – SeaDude Jan 13 '20 at 05:18
-
"or branch names in other repositories in the same network as `:repo`" : what exactly is a "repository in the same network" ? Is a fork such a thing? (If I want to compare the `master` from the original repository with the `master` of one of its forks.) – payne Oct 11 '20 at 05:46
-
1@payne Yes, you can compare a fork, if it is hosted on the same service (like "github.com") as the original repo. I have edited the answer to add an example. See the last section "Notes". – VonC Oct 11 '20 at 09:07
-
1@VonC great edit, thanks! I started integrating that in an extension, but unfortunately the GitHub API Doc doesn't give descriptions for the different parameters. I'm always getting the same number for `ahead_by` and `total_commits`: would you happen to know the difference? – payne Oct 12 '20 at 20:32
-
@payne It is true https://docs.github.com/en/free-pro-team@latest/rest/reference/repos#compare-two-commits does not detail those two fields. I mentioned them in https://stackoverflow.com/a/37527495/6309. I suspect if a branch was merged to the other branch you are comparing it to, it would not be ahead (`ahead_by: 0`) but it would still have a `total_commits` positive. – VonC Oct 12 '20 at 21:08
-
Please note this suggested API silently maxes out at 300 files shown; I haven't yet found an API that avoids this limitation https://docs.github.com/en/repositories/creating-and-managing-repositories/about-repositories#diff-limits – Tom Carver May 27 '22 at 12:34
-
1@TomCarver Good point. I have included your comment in the answer for more visibility. – VonC May 27 '22 at 15:23
Investigating answers coming with the official API, one can find a barely mentioned way to get diffs from Github. Try this:
wget -H 'Accept: application/vnd.github.v3.diff' \
http://github.com/github/linguist/compare/96d29b76...a20631af.diff
wget -H 'Accept: application/vnd.github.v3.diff' \
http://github.com/github/linguist/compare/a20631af...96d29b76.diff
This is the link you provided as an example, with .diff
appended. And the reverse diff of the same.
The header given makes sure the request is handled by the Github's v3 API. That's currently the default, but might change in the future. See Media Types.
Why two downloads?
Github serves linear diffs from older to newer versions, only. If the requested diff is indeed linear and from an older to a newer version, the second download will be empty.
If the requested diff is linear, but from a newer to an older version, the first download is empty. Instead, the whole diff is in the second download. Depending on what one want to achieve, one can normally apply it to the newer version or reverse-apply (patch -R
) it to the older version.
If there is no linear relationship between the pair of requested commits, both downloads get answered with non-zero content. One from the common anchestor to the first commit and another, reversed one from this common anchestor to the other commit. Applying one diff normally and the other one reversed gives what applying the output of git diff 96d29b76..a20631af
would give, too.
As far as I can tell, these raw diffs aren't subject to Github's API limitations. Requests for 540 commits with 1002 file changes went flawlessly.
Note: one can also append .patch
instead of .diff
. Then one still gets one big file for each, but a set of individual patches for each commit inside this file.

- 194
- 2
- 10
-
P.S.: instead of SHAs, one can also request tags or branches, or combinations of these, of course. – Traumflug Jun 09 '17 at 12:49
Traumflug's answer isn't correct if you are using the API to access private repos. Actually, I think that answer doesn't require the header since it works without it in a public repo anyways.
You should not put the .diff
at the end of the url and you should use the api
subdomain. If you want the diff specifically, you only need to put the appropriate media type header in the request (and the token for authentication).
So for example:
wget -H 'Accept: application/vnd.github.v3.diff' \
https://api.github.com/repos/github/linguist/compare/96d29b76...a20631af?access_token=123
GitHub's documentation is super confusing since it says it only works for branch names, but it also accepts commit shas. Also, the returned JSON includes a diff_url
that is just a direct link to the diff but does not work if the repo is private, which isn't very helpful.

- 4,739
- 1
- 33
- 46

- 311
- 1
- 4
- 11
-
Thank you! Was looking for someone to verify that it works for SHAs, going to try it myself shortly to confirm – Arie Milner May 30 '19 at 00:36
-
Just tested it and it worked, used commit SHAs for both the base and head. Thank you again! – Arie Milner May 30 '19 at 00:48
Here's another actual executable example using the HEAD
and HEAD~1
references on my public repo DataApp--ParamCompare which should help illuminate the :owner
and :repo
notation once substituted with clear parameters.
curl -X GET https://api.github.com/repos/jxramos/DataApp--ParamCompare/compare/HEAD~1...HEAD
As a sanity check the equivalent browser representation can be seen at https://github.com/jxramos/DataApp--ParamCompare/compare/HEAD~1...HEAD
In general the form goes as the following to lend an alternate parameter syntax for the api routing:
https://api.github.com/repos/<owner_name>/<repo_name>/compare/HEAD~1...HEAD
One can also invoke a url such as
https://api.github.com/repos/jxramos/DataApp--ParamCompare/compare/80f0bb42606888ce7fc66b4402fcc90a1709c9e8...255fe089543f5569f90af54168af904e88fc150f
There should be an equivalent graphql means to just pare down and select those results under the files
list to select all the filename
values to lend something of a git diff --name-only
type output straight from remote. I'll update this answer if I figure it out.
My take on this is that the graphql API doesn't conduct operations which is what a diff is, but rather allows to to query primitive types and properties and the like of the repo itself. You can see the sort of entities you're dealing with by looking at the schema itself https://developer.github.com/v4/public_schema/

- 7,356
- 6
- 57
- 105
-
I need only the file names between two commits. Have you figured out how to do it? – T3rm1 Apr 17 '20 at 06:33
-
1No, I actually don't think graphql supports diffs, it just allows you to navigate raw properties and fields of the repo... https://developer.github.com/v4/public_schema/ – jxramos Apr 17 '20 at 07:33