GitHub API-как сравнить 2 коммита

можно получить список измененных файлов между двумя коммитами. Что-то вроде того сравнение двух коммитов в веб-версии, но, используя GitHub Api.

3 ответов


официальным API сравнения фиксации является сравнить два коммита:

GET /repos/:owner/:repo/compare/:base...:head

и :base и :head могут быть имена ветвей в: repo или имена ветвей в других репозиториях в той же сети, что и :repo. В последнем случае, используйте формат user:branch:

GET /repos/:owner/:repo/compare/user1:branchname...user2:branchname

обратите внимание, что вы также можете использовать теги.
Для пример:

https://api.github.com/repos/git/git/compare/v2.2.0-rc1...v2.2.0-rc2

обратите внимание на '...', а не '..' между двумя тегами.
И сначала вам нужно иметь самый старый тег, а затем более новый тег.

это дает статус:

  "status": "behind",
  "ahead_by": 1,
  "behind_by": 2,
  "total_commits": 1,

и для каждой фиксации информация о файлах:

"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"
    }
  ]

но:

  • ответ будет включать сравнение до 250 коммитов. Если вы работаете с большим диапазоном фиксации, вы можете использовать API списка фиксации для перечисления всех коммитов в диапазоне.

  • для сравнения с чрезвычайно большими различиями вы можете получить ответ об ошибке, указывающий, что разница заняла слишком много времени. Обычно эту ошибку можно устранить с помощью меньшего диапазона фиксации.


изучение ответов, поступающих с официальным API, можно найти едва упомянутый способ получить различия от Github. Попробуйте это:

  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

это ссылка, которую вы предоставили в качестве примера, с .diff прилагается. И обратное различие то же самое.

данный заголовок гарантирует, что запрос обрабатывается API v3 Github. В настоящее время это значение по умолчанию, но может измениться в будущем. См.Типы Носителей.

почему два загрузки?

GitHub обслуживает только линейные различия от старых до новых версий. Если запрошенный diff действительно линейный и от более старой до более новой версии, вторая загрузка будет пустой.

если запрошенный diff линейный, но от более новой до более старой версии, первая загрузка пуста. Вместо этого весь diff находится во второй загрузке. В зависимости от того, чего вы хотите достичь, обычно можно применить его к более новой версии или применить наоборот (patch -R) это более старая версия.

если нет линейной связи между парой запрошенных коммитов, обе загрузки получают ответ с ненулевым контентом. Один из общие anchestor для первого коммита, а другой, обращенный одним из этой общей anchestor на другой коммит. Применение одного различия нормально, а другого наоборот дает то, что применение вывода git diff 96d29b76..a20631af дали бы тоже.

насколько я могу судить, эти необработанные различия не подлежат API Github ограничения. Запросы на 540 коммитов со 1002 изменениями файлов прошли безупречно.

Примечание: Можно также добавить .patch вместо .diff. Тогда все равно получается один большой файл для каждого, но набор отдельных патчей для каждой фиксации внутри этого файла.


ответ Traumflug неверен, если вы используете API для доступа к частным репозиториям. На самом деле, я думаю, что ответ не требует заголовка, так как он работает без него в публичном РЕПО.

вы не должны положить .diff в конце url-адреса, и вы должны использовать поддомен api. Если вы хотите, чтобы diff конкретно, вам нужно только поместить соответствующий заголовок типа носителя в запрос (и маркер для аутентификации).

Так для пример:

  wget -H 'Accept: application/vnd.github.v3.diff' \
    https://api.github.com/repos/github/linguist/compare/96d29b76...a20631af?access_token=123

документация Gitlab очень запутанная, так как она говорит это только работает для имен ветвей, но он также принимает фиксацию shas. Кроме того, возвращаемый JSON включает в себя diff_url это просто прямая ссылка на diff, но не работает, если РЕПО является частным, что не очень полезно.