You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现GitHub Compare Commit API返回结果的分页

核心原因

GitHub Compare Commit 接口本身不支持标准分页逻辑,接口硬编码限制单次返回最多300个变更文件,传入per_page、page等常规分页参数不会生效,响应头也不会生成分页用的Link字段,和你请求写法是否正确没有关系,翻官方分页指南找不到对应方案是正常的。

替代实现方案

要拿到两个commit/分支之间的全量变更文件,只能绕开原生compare接口,用支持分页的commits列表接口搭配单commit详情查询曲线实现,逻辑如下:

  • 分页拉取base节点到head节点之间的所有commit列表,直到遍历到base节点为止
  • 逐个查询每个commit的变更文件列表
  • 对重复出现的文件路径做去重,最终得到全量变更文件集合

JavaScript可运行实现代码如下:

async function getFullCompareFileList(owner, repo, baseRef, headRef, githubToken) {
  const requestHeaders = {
    'Accept': 'application/vnd.github+json',
    'Authorization': `Bearer ${githubToken}`,
    'X-GitHub-Api-Version': '2022-11-28'
  };
  const changedFileSet = new Set();
  let currentPage = 1;
  let stopFetch = false;

  while (!stopFetch) {
    // 拉取当前页的commit列表
    const commitListResp = await fetch(
      `https://api.github.com/repos/${owner}/${repo}/commits?sha=${headRef}&per_page=100&page=${currentPage}`,
      { headers: requestHeaders }
    );
    if (!commitListResp.ok) {
      throw new Error(`拉取commit列表失败,状态码:${commitListResp.status}`);
    }
    const commitList = await commitListResp.json();
    if (commitList.length === 0) break;

    for (const commitItem of commitList) {
      // 遍历到基准commit时停止拉取
      if (commitItem.sha.startsWith(baseRef)) {
        stopFetch = true;
        break;
      }
      // 拉取单个commit的详情,获取变更文件
      const commitDetailResp = await fetch(
        `https://api.github.com/repos/${owner}/${repo}/commits/${commitItem.sha}`,
        { headers: requestHeaders }
      );
      if (!commitDetailResp.ok) {
        throw new Error(`拉取commit ${commitItem.sha} 详情失败,状态码:${commitDetailResp.status}`);
      }
      const commitDetail = await commitDetailResp.json();
      commitDetail.files.forEach(file => changedFileSet.add(file.filename));
    }
    currentPage++;
  }

  return Array.from(changedFileSet);
}

// 调用示例
// getFullCompareFileList('仓库所属组织/用户名', '仓库名', '基准commit/分支', '目标commit/分支', '你的GitHub个人访问令牌')
//   .then(fileList => console.log('全量变更文件:', fileList))
//   .catch(err => console.error('执行失败:', err));
使用说明
  • 必须传入有效的GitHub个人访问令牌,未鉴权的API请求每小时仅60次额度,很容易触发限流;鉴权后每小时额度为5000次,可满足绝大多数场景需求
  • 如果两个比对节点之间commit数量极大,会产生较多API请求,建议根据业务场景加本地缓存,减少重复请求
  • 该方案返回的结果和原生compare接口的文件列表一致,同时可以突破原生接口最多返回300个文件的限制

内容的提问来源于stack exchange,提问作者Andrew B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 22:54:37