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

如何用Git统计两个Commit间的代码细分(含历史修改时间维度)

实现三类代码行细分统计的方法

Git没有原生命令直接输出你需要的三类统计,得结合git diff、git blame和脚本逻辑来完成——核心是追踪变更行的历史修改时间,以此区分Refactored和Reworked行。

核心思路拆解

  • NewLines:直接统计两个commit间diff里以+开头的行(排除diff头部的+++行)
  • RefactoredLines/ReworkedLines:对diff中被删除/修改的原行(以-开头的行),用git blame查询该行在旧commit中的最后修改时间,判断是否超过30天,分别归类

可运行的Bash脚本示例

以下脚本接收两个commit ID作为参数,自动统计三类行的数量:

#!/bin/bash

# 检查参数是否齐全
if [ $# -ne 2 ]; then
    echo "用法: $0 <旧commit ID> <新commit ID>"
    exit 1
fi

COMMIT_OLD=$1
COMMIT_NEW=$2

# 初始化统计变量
NEW_LINES=0
REFACTORED_LINES=0
REWORKED_LINES=0

# 计算30天前的时间戳(单位:秒)
THIRTY_DAYS_AGO=$(date -d "30 days ago" +%s)

# 遍历所有有变更的文件
git diff --name-only "$COMMIT_OLD" "$COMMIT_NEW" | while read -r FILE; do
    # 获取当前文件的diff块信息(无上下文)
    git diff -U0 "$COMMIT_OLD" "$COMMIT_NEW" -- "$FILE" | grep '^@@' | while read -r HUNK; do
        # 提取旧版本中该diff块的起始行号和行数
        OLD_RANGE=$(echo "$HUNK" | awk '{print $2}' | sed 's/^-//')
        OLD_START=$(echo "$OLD_RANGE" | cut -d',' -f1)
        OLD_COUNT=$(echo "$OLD_RANGE" | cut -d',' -f2)
        [ -z "$OLD_COUNT" ] && OLD_COUNT=1

        # 遍历该块内的每一行(旧版本中的行)
        for ((i=0; i<OLD_COUNT; i++)); do
            LINE_NUM=$((OLD_START + i))
            # 获取该行最后一次修改的时间戳
            BLAME_COMMIT=$(git blame -L $LINE_NUM,$LINE_NUM "$COMMIT_OLD" -- "$FILE" | awk '{print $1}')
            COMMIT_TIME=$(git show -s --format=%at "$BLAME_COMMIT")

            # 判断时间归属类别
            if [ "$COMMIT_TIME" -lt "$THIRTY_DAYS_AGO" ]; then
                ((REFACTORED_LINES++))
            else
                ((REWORKED_LINES++))
            fi
        done
    done

    # 统计当前文件的新增行
    ADD_LINES=$(git diff -U0 "$COMMIT_OLD" "$COMMIT_NEW" -- "$FILE" | grep '^+' | grep -v '^+++' | wc -l)
    NEW_LINES=$((NEW_LINES + ADD_LINES))
done

# 输出最终统计结果
echo "=== 代码行统计结果 ==="
echo "- NewLines: $NEW_LINES"
echo "- RefactoredLines: $REFACTORED_LINES"
echo "- ReworkedLines: $REWORKED_LINES"

使用说明

  1. 将脚本保存为code_stat.sh,赋予执行权限:chmod +x code_stat.sh
  2. 运行脚本:./code_stat.sh <旧commit> <新commit>(比如./code_stat.sh abc123 def456)

注意事项

  • 脚本依赖Bash环境和Git,确保已安装
  • 对于大型仓库或大量变更的commit,脚本运行速度会较慢(因为要对每行执行git blame),可以通过批量导出git blame信息来优化
  • 脚本中会自动跳过diff的头部信息,只统计实际的代码变更行

简化替代方案(非精确)

如果不需要严格精确到每行的修改时间,可以用以下思路快速估算:

  1. 用git diff --stat获取总插入/删除数,得到NewLines的近似值
  2. 用git log --since="30 days ago" --oneline "$COMMIT_OLD".."$COMMIT_NEW"获取最近30天内的commit,对这些commit执行git diff --stat统计ReworkedLines,剩余的删除/修改行即为RefactoredLines
  • 这种方法误差较大,因为是基于commit提交时间而非行的最后修改时间,仅适合粗略统计

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 15:50:26