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

无需git命令从GitHub仓库Git diff文件统计代码变更行数

解决方案

以下两种实现均满足无本地Git环境、无仓库访问权限的限制,只需要传入diff文本内容即可完成统计。

方案1:使用成熟diff解析库(推荐)

采用纯Python编写的unidiff库解析标准unified diff格式,无任何系统级依赖,不需要安装Git,已经覆盖二进制文件标记、文件重命名、多hunk分段、无末尾换行提示等各类边缘场景,统计准确率远高于手写临时解析逻辑。
安装命令:

pip install unidiff

实现代码:

from unidiff import PatchSet

def calc_diff_stats(diff_content_list: list[str]) -> tuple[int, int, list[dict]]:
    """
    统计diff文件的变更数据
    :param diff_content_list: 所有diff文件的原始文本内容组成的列表
    :return: 总新增行数、总删除行数、单文件统计结果列表
    """
    total_add = 0
    total_remove = 0
    per_file_stats = []
    for diff_text in diff_content_list:
        patch = PatchSet(diff_text)
        file_add = 0
        file_remove = 0
        for file in patch:
            for hunk in file:
                for line in hunk:
                    if line.is_added:
                        file_add += 1
                    if line.is_removed:
                        file_remove += 1
        per_file_stats.append({
            "added_lines": file_add,
            "removed_lines": file_remove,
            "total_changed_lines": file_add + file_remove
        })
        total_add += file_add
        total_remove += file_remove
    return total_add, total_remove, per_file_stats

if __name__ == "__main__":
    # 替换为实际读取到的所有diff文件内容
    diff_files = [open("pull_request.diff", "r", encoding="utf-8").read()]
    add, remove, _ = calc_diff_stats(diff_files)
    print(f"total lines added = {add}, total lines removed = {remove}")

用你提供的示例diff测试,输出结果为total lines added = 2, total lines removed = 0,和实际变更完全一致。

方案2:纯标准库轻量实现

如果不想引入第三方依赖,可以直接按照unified diff的语法规则逐行遍历统计,核心判断逻辑如下:

  • 跳过所有元信息行:包括文件头(以diff --git、index 、--- 、+++ 开头)、hunk位置标记(以@@开头)、diff注释(以\开头,比如No newline at end of file提示)
  • 剩余行中,以+开头的计入新增行数,以-开头的计入删除行数,其余为未变更的上下文行,不计入增删统计
    实现代码:
def calc_diff_stats_no_dep(diff_content_list: list[str]) -> tuple[int, int]:
    total_add = 0
    total_remove = 0
    for diff_text in diff_content_list:
        for line in diff_text.splitlines():
            # 跳过所有非内容的标记行
            if (
                line.startswith("diff --git")
                or line.startswith("index ")
                or line.startswith("--- ")
                or line.startswith("+++ ")
                or line.startswith("@@")
                or line.startswith("\\")
            ):
                continue
            if line.startswith("+"):
                total_add += 1
            elif line.startswith("-"):
                total_remove += 1
    return total_add, total_remove

if __name__ == "__main__":
    diff_files = [open("pull_request.diff", "r", encoding="utf-8").read()]
    add, remove = calc_diff_stats_no_dep(diff_files)
    print(f"total lines added = {add}, total lines removed = {remove}")

可选GitHub原生方案

由于目标仓库托管在GitHub,你也可以直接调用GitHub的PR相关接口,接口返回的结构化数据中直接自带additions、deletions统计字段,不需要自行解析diff文本,适合批量统计大量PR的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 11:24:22