【问题标题】:Get the metadata for the first N commits in a remote Git repository获取远程 Git 存储库中前 N 次提交的元数据
【发布时间】:2020-09-15 09:01:09
【问题描述】:

使用以下 GitHub API,可以获取存储库中提交的元数据,按从最新到最旧的顺序排列

https://api.github.com/repos/git/git/commits

有没有办法获得类似的元数据,但按提交的时间倒序,即从存储库中最旧的提交开始?

注意:我想获得这样的元数据,而不必下载完整的存储库。

谢谢

【问题讨论】:

  • 这很难。 Git 不维护前向链接,只维护后向链接。所以你必须从一个分支的头部开始,然后遍历到根,收集提交之间的链接。之后,您可以反转链接列表。
  • @phd 所以这意味着无法直接访问“第一次提交”,我必须从某个地方(即任何提交)开始,然后通过提交图及时返回。
  • 是的,没错。 Git 不维护前向链接,因为它们可以更改;如果发生此类更改,则必须使用新的前向链接更新先前的提交——但这意味着修改历史记录、强制推送等各种问题。

标签: git github github-api


【解决方案1】:

这可以通过使用GraphQL API 的解决方法来实现。这个方法和getting the first commit in a repo基本一样:

获取last commit 并返回totalCountendCursor

{
  repository(name: "linux", owner: "torvalds") {
    ref(qualifiedName: "master") {
      target {
        ... on Commit {
          history(first: 1) {
            nodes {
              message
              committedDate
              authoredDate
              oid
              author {
                email
                name
              }
            }
            totalCount
            pageInfo {
              endCursor
            }
          }
        }
      }
    }
  }
}

它为光标和pageInfo 对象返回类似的内容:

"totalCount": 950329,
"pageInfo": {
  "endCursor": "b961f8dc8976c091180839f4483d67b7c2ca2578 0"
}

我没有关于光标字符串格式 b961f8dc8976c091180839f4483d67b7c2ca2578 0 的任何来源,但我已经使用其他一些提交超过 1000 次的存储库进行了测试,它似乎总是格式化为:

<static hash> <incremented_number>

为了从第一个提交迭代到最新提交,您需要从第 1 页开始从totalCount - 1 - &lt;number_perpage&gt;*&lt;page&gt; 开始:

例如,为了从 linux 存储库中获取前 20 个提交:

{
  repository(name: "linux", owner: "torvalds") {
    ref(qualifiedName: "master") {
      target {
        ... on Commit {
          history(first: 20, after: "fc4f28bb3daf3265d6bc5f73b497306985bb23ab 950308") {
            nodes {
              message
              committedDate
              authoredDate
              oid
              author {
                email
                name
              }
            }
            totalCount
            pageInfo {
              endCursor
            }
          }
        }
      }
    }
  }
}

请注意,此 repo 中的总提交计数会随时间变化,因此您需要在运行查询之前获取总计数值。

这是一个 示例迭代 Linux 存储库的前 300 次提交(从最旧的开始):

import requests

token = "YOUR_ACCESS_TOKEN"

name = "linux"
owner = "torvalds"
branch = "master"

iteration = 3
per_page = 100
commits = []

query = """
query ($name: String!, $owner: String!, $branch: String!){
    repository(name: $name, owner: $owner) {
        ref(qualifiedName: $branch) {
            target {
                ... on Commit {
                    history(first: %s, after: %s) {
                        nodes {
                            message
                            committedDate
                            authoredDate
                            oid
                            author {
                                email
                                name
                            }
                        }
                        totalCount
                        pageInfo {
                            endCursor
                        }
                    }
                }
            }
        }
    }
}
"""

def getHistory(cursor):
    r = requests.post("https://api.github.com/graphql",
        headers = {
            "Authorization": f"Bearer {token}"
        },
        json = {
            "query": query % (per_page, cursor),
            "variables": {
                "name": name,
                "owner": owner,
                "branch": branch
            }
        })
    return r.json()["data"]["repository"]["ref"]["target"]["history"]

#in the first request, cursor is null
history = getHistory("null")
totalCount = history["totalCount"]
if (totalCount > 1):
    cursor = history["pageInfo"]["endCursor"].split(" ")
    for i in range(1, iteration + 1):
        cursor[1] = str(totalCount - 1 - i*per_page)
        history = getHistory(f"\"{' '.join(cursor)}\"")
        commits += history["nodes"][::-1]
else:
    commits = history["nodes"]

print(commits)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 2020-09-06
    • 2012-01-03
    • 2011-06-06
    • 2021-07-20
    相关资源
    最近更新 更多