You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用GitPython获取文件增删行数并调整输出格式提取信息?

使用GitPython实现类似git diff --numstat的统计功能

我来帮你解决这个问题——用GitPython实现类似git diff --numstat的文件增删行数统计,并且能轻松提取每个文件的有效数据:

1. 先安装GitPython

首先确保你已经安装了GitPython库:

pip install gitpython

2. 基础实现:复刻git diff --numstat输出

下面的代码会遍历所有修改过的文件,按照git diff --numstat的格式输出新增行数、删除行数和文件名,同时处理重命名、二进制文件等特殊情况:

from git import Repo

# 替换为你的Git仓库路径
repo_path = "/path/to/your/git/repository"
repo = Repo(repo_path)

# 获取工作区与HEAD的差异(对应`git diff`命令)
# 如果需要暂存区与HEAD的差异,用 repo.head.commit.diff()
# 如果要对比两个特定commit,用 repo.commit("old_commit_hash").diff("new_commit_hash")
diff_index = repo.index.diff(repo.head.commit)

print("新增行数\t删除行数\t文件名")
print("-------------------------------")

for diff in diff_index:
    # 处理文件名:重命名文件显示新旧路径,否则显示当前路径
    if diff.renamed:
        filename = f"{diff.a_path} -> {diff.b_path}"
    else:
        filename = diff.b_path if diff.b_path else diff.a_path
    
    # 处理二进制文件:git diff --numstat中二进制文件显示"- -"
    if diff.binary:
        insertions = "-"
        deletions = "-"
    else:
        # 从diff统计中提取增删行数
        insertions = diff.stats["insertions"]
        deletions = diff.stats["deletions"]
    
    # 按照numstat格式打印
    print(f"{insertions}\t{deletions}\t{filename}")

3. 提取结构化数据(方便后续处理)

如果你不想直接打印,而是要把增删行数提取为字典等结构化数据,方便后续分析,可以这样写:

from git import Repo

repo = Repo("/path/to/your/git/repository")
diff_index = repo.index.diff(repo.head.commit)

# 用字典存储每个文件的统计信息
file_stats = {}

for diff in diff_index:
    # 跳过二进制文件(也可以根据需求保留)
    if diff.binary:
        continue
    
    # 确定文件名
    if diff.renamed:
        file_key = f"{diff.a_path} -> {diff.b_path}"
    else:
        file_key = diff.b_path if diff.b_path else diff.a_path
    
    # 存储增删行数
    file_stats[file_key] = {
        "insertions": diff.stats["insertions"],
        "deletions": diff.stats["deletions"]
    }

# 遍历结构化数据进行处理
for file, stats in file_stats.items():
    print(f"文件 {file}: 新增 {stats['insertions']} 行,删除 {stats['deletions']} 行")

4. 常见扩展场景

  • 对比暂存区与HEAD:把diff_index = repo.index.diff(repo.head.commit)换成diff_index = repo.head.commit.diff(),对应git diff --cached --numstat
  • 对比两个历史commit:比如对比abc123def456两个commit,用diff_index = repo.commit("abc123").diff("def456")
  • 处理空差异:可以先判断if not diff_index: print("当前没有修改的文件"),避免空遍历

注意事项

  • 确保你的GitPython版本是较新的,旧版本可能存在API差异
  • 如果是裸仓库(bare repository),部分diff操作会受限,建议使用带工作区的仓库
  • 对于大型仓库,diff操作可能会耗时较长,可以考虑按需过滤文件(比如只统计特定目录下的文件)

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

火山引擎 最新活动