如何使用GitHub V3 API来获取repo的提交次数?

Ste*_*man 16 git github github-api

我正在尝试使用API 计算许多大型github存储库的提交,所以我想避免获取整个提交列表(这种方式作为示例:api.github.com/repos/jasonrudolph/keyboard/commits)和计数他们.

如果我有第一个(初始)提交的哈希值,我可以使用这种技术将第一个提交与最新提交进行比较,并愉快地报告两者之间的total_commits(所以我需要添加一个).不幸的是,我看不出如何使用API​​优雅地获得第一次提交.

基本的repo URL确实给了我created_at(这个url是一个例子:api.github.com/repos/jasonrudolph/keyboard),所以我可以通过限制提交到创建日期来获得减少的提交集(这个url是一个例子:api.github.com/repos/jasonrudolph/keyboard/commits?until=2013-03-30T16:01:43Z)并使用最早的一个(总是列在最后?)或者可能是空父母的一个(不确定分叉项目是否有初始父提交).

获得repo的第一个提交哈希的更好方法是什么?

更好的是,对于一个简单的统计来说,整个事情似乎很复杂,我想知道我是否遗漏了一些东西.使用API​​获取repo提交计数的任何更好的想法?

编辑:这个有点类似的问题是试图过滤某些文件("并在其中的特定文件."),所以有一个不同的答案.

Sha*_*shi 16

提出请求https://api.github.com/repos/{username}/{repo}/commits?sha={branch}&per_page=1&page=1

现在只需获取Link响应标头的参数并获取之前的页数rel="last"

此页数等于该分支中的提交总数!

诀窍是使用&per_page=1&page=1. 它在 1 页中分发了 1 次提交。因此,提交总数将等于页面总数。

  • 非常聪明、巧妙的伎俩。 (3认同)

Iva*_*zak 10

如果您要查找默认分支中的提交总数,可以考虑采用不同的方法.

使用Repo Contributors API获取所有贡献者的列表:

https://developer.github.com/v3/repos/#list-contributors

列表中的每个项目都将包含一个contributions字段,该字段告诉您用户在默认分支中创建了多少提交.在所有贡献者中对这些字段求和,您应该获得默认分支中的提交总数.

贡献者列表通常比提交列表短得多,因此应该花费更少的请求来计算默认分支中的提交总数.

  • GitHub为什么不将提交计数包括在API响应中?令人失望的是,必须不必要地遍历贡献者列表。 (2认同)
  • 请注意,如果从您的存储库/组织/任何人中删除了任何用户(例如,一名雇员离开公司),此方法将返回错误的号码。 (2认同)

Ber*_*tel 6

您可以考虑使用GraphQL API v4使用别名对多个存储库同时执行提交计数。以下将获取3个不同存储库的所有分支的提交计数(每个存储库最多100个分支):

{
  gson: repository(owner: "google", name: "gson") {
    ...RepoFragment
  }
  martian: repository(owner: "google", name: "martian") {
    ...RepoFragment
  }
  keyboard: repository(owner: "jasonrudolph", name: "keyboard") {
    ...RepoFragment
  }
}

fragment RepoFragment on Repository {
  name
  refs(first: 100, refPrefix: "refs/heads/") {
    edges {
      node {
        name
        target {
          ... on Commit {
            id
            history(first: 0) {
              totalCount
            }
          }
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在资源管理器中尝试

RepoFragment是一个片段,可帮助避免每个存储库的重复查询字段

如果只需要默认分支上的提交计数,则更加简单:

{
  gson: repository(owner: "google", name: "gson") {
    ...RepoFragment
  }
  martian: repository(owner: "google", name: "martian") {
    ...RepoFragment
  }
  keyboard: repository(owner: "jasonrudolph", name: "keyboard") {
    ...RepoFragment
  }
}

fragment RepoFragment on Repository {
  name
  defaultBranchRef {
    name
    target {
      ... on Commit {
        id
        history(first: 0) {
          totalCount
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在资源管理器中尝试

  • @Mahesh 是的,如果您只想请求公共内容或从 Web 客户端使用 api,那么这是 graphQL api 的一个很大的警告。仅在可以安全存储访问令牌的环境中才能使用 graphql api,否则只需坚持使用 Rest api v3 (2认同)

buc*_*ley 6

如果您开始新项目,则使用 GraphQL API v4 可能是处理此问题的方法,但如果您仍在使用 REST API v3,则可以通过将请求限制为每个结果仅 1 个来解决分页问题。页。通过设置该限制,最后一个链接返回的数量pages将等于总数。

例如使用 python3 和 requests 库

def commit_count(project, sha='master', token=None):
    """
    Return the number of commits to a project
    """
    token = token or os.environ.get('GITHUB_API_TOKEN')
    url = f'https://api.github.com/repos/{project}/commits'
    headers = {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authorization': f'token {token}',
    }
    params = {
        'sha': sha,
        'per_page': 1,
    }
    resp = requests.request('GET', url, params=params, headers=headers)
    if (resp.status_code // 100) != 2:
        raise Exception(f'invalid github response: {resp.content}')
    # check the resp count, just in case there are 0 commits
    commit_count = len(resp.json())
    last_page = resp.links.get('last')
    # if there are no more pages, the count must be 0 or 1
    if last_page:
        # extract the query string from the last page url
        qs = urllib.parse.urlparse(last_page['url']).query
        # extract the page number from the query string
        commit_count = int(dict(urllib.parse.parse_qsl(qs))['page'])
    return commit_count
Run Code Online (Sandbox Code Playgroud)


sno*_*owe 5

简单的解决办法:看页码。Github 为你分页。因此,您只需从链接标题中获取最后一个页码,减去一个(您需要手动添加最后一页),乘以页面大小,获取最后一页结果和获取该数组的大小并将两个数字相加。最多两个 API 调用!

这是我使用 ruby​​ 中的 octokit gem 获取整个组织的提交总数的实现:

@github = Octokit::Client.new access_token: key, auto_traversal: true, per_page: 100

Octokit.auto_paginate = true
repos = @github.org_repos('my_company', per_page: 100)

# * take the pagination number
# * get the last page
# * see how many items are on it
# * multiply the number of pages - 1 by the page size
# * and add the two together. Boom. Commit count in 2 api calls
def calc_total_commits(repos)
    total_sum_commits = 0

    repos.each do |e| 
        repo = Octokit::Repository.from_url(e.url)
        number_of_commits_in_first_page = @github.commits(repo).size
        repo_sum = 0
        if number_of_commits_in_first_page >= 100
            links = @github.last_response.rels

            unless links.empty?
                last_page_url = links[:last].href

                /.*page=(?<page_num>\d+)/ =~ last_page_url
                repo_sum += (page_num.to_i - 1) * 100 # we add the last page manually
                repo_sum += links[:last].get.data.size
            end
        else
            repo_sum += number_of_commits_in_first_page
        end
        puts "Commits for #{e.name} : #{repo_sum}"
        total_sum_commits += repo_sum
    end
    puts "TOTAL COMMITS #{total_sum_commits}"
end
Run Code Online (Sandbox Code Playgroud)

是的,我知道代码很脏,这只是在几分钟内拼凑起来的。

  • 没有使用您的代码,但查看标题链接中的页码的想法为我节省了许多 API 调用。谢谢 (2认同)