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

如何实现与VS Code源代码控制一致的Git变更行数统计

实现VS Code风格的Git变更行数统计

要把git diff --unified=0的输出转换成「第X行已删除」「第X-Y行已添加」这类格式,核心是解析diff输出中的变更块(hunk)头部信息,结合变更行统计计算连续行范围。

关键原理

git diff --unified=0的每个变更块头部格式为:

@@ -原始起始行[,原始行数] +新文件起始行[,新文件行数] @@

比如@@ -3,2 +1,3 @@表示:原始文件第3行开始的2行被修改,新文件对应位置从第1行开始新增3行。我们需要通过这个头部信息,搭配块内的删除/添加行统计,计算出连续的行范围。

Python实现脚本

import subprocess
import re

def parse_git_diff():
    # 执行git diff命令获取无上下文差异
    result = subprocess.run(['git', 'diff', '--unified=0'], capture_output=True, text=True)
    diff_output = result.stdout

    # 匹配hunk头部的正则表达式
    hunk_regex = re.compile(r'@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@')
    current_hunk = None
    delete_ranges = []
    add_ranges = []

    for line in diff_output.splitlines():
        hunk_match = hunk_regex.match(line)
        if hunk_match:
            # 处理上一个hunk的结果
            if current_hunk:
                process_hunk(current_hunk, delete_ranges, add_ranges)
            # 提取当前hunk的行数据
            orig_start = int(hunk_match.group(1))
            orig_count = int(hunk_match.group(2)) if hunk_match.group(2) else 1
            new_start = int(hunk_match.group(3))
            new_count = int(hunk_match.group(4)) if hunk_match.group(4) else 1
            current_hunk = {
                'orig_start': orig_start,
                'orig_count': orig_count,
                'new_start': new_start,
                'new_count': new_count,
                'delete_count': 0,
                'add_count': 0
            }
        elif current_hunk:
            if line.startswith('-'):
                current_hunk['delete_count'] += 1
            elif line.startswith('+'):
                current_hunk['add_count'] += 1
    # 处理最后一个hunk
    if current_hunk:
        process_hunk(current_hunk, delete_ranges, add_ranges)
    
    # 格式化输出结果
    for start, end in delete_ranges:
        print(f「第{start}行已删除」) if start == end else print(f「第{start}-{end}行已删除」)
    for start, end in add_ranges:
        print(f「第{start}行已添加」) if start == end else print(f「第{start}-{end}行已添加」)

def process_hunk(hunk, delete_ranges, add_ranges):
    # 计算删除行的连续范围
    if hunk['delete_count'] == hunk['orig_count']:
        delete_end = hunk['orig_start'] + hunk['orig_count'] - 1
        delete_ranges.append((hunk['orig_start'], delete_end))
    # 计算添加行的连续范围
    if hunk['add_count'] == hunk['new_count']:
        add_end = hunk['new_start'] + hunk['new_count'] - 1
        add_ranges.append((hunk['new_start'], add_end))

if __name__ == '__main__':
    parse_git_diff()

Shell脚本实现

git diff --unified=0 | grep -E '^@@|^-|^+' | awk '
    /^@@/ {
        # 输出上一个hunk的结果
        if (orig_start != "") {
            # 处理删除行范围
            if (delete_count > 0) {
                delete_end = orig_start + delete_count - 1
                if (orig_start == delete_end) {
                    print "「第" orig_start "行已删除」"
                } else {
                    print "「第" orig_start "-" delete_end "行已删除」"
                }
            }
            # 处理添加行范围
            if (add_count > 0) {
                add_end = new_start + add_count - 1
                if (new_start == add_end) {
                    print "「第" new_start "行已添加」"
                } else {
                    print "「第" new_start "-" add_end "行已添加」"
                }
            }
        }
        # 解析当前hunk的行信息
        split($2, orig_parts, /[,+-]/)
        orig_start = orig_parts[2] + 0
        orig_count = orig_parts[3] + 0
        orig_count = orig_count == 0 ? 1 : orig_count
        
        split($3, new_parts, /[,+-]/)
        new_start = new_parts[2] + 0
        new_count = new_parts[3] + 0
        new_count = new_count == 0 ? 1 : new_count
        
        delete_count = 0
        add_count = 0
    }
    /^-/ { delete_count++ }
    /^+/ { add_count++ }
    END {
        # 处理最后一个hunk
        if (orig_start != "") {
            if (delete_count > 0) {
                delete_end = orig_start + delete_count - 1
                if (orig_start == delete_end) {
                    print "「第" orig_start "行已删除」"
                } else {
                    print "「第" orig_start "-" delete_end "行已删除」"
                }
            }
            if (add_count > 0) {
                add_end = new_start + add_count - 1
                if (new_start == add_end) {
                    print "「第" new_start "行已添加」"
                } else {
                    print "「第" new_start "-" add_end "行已添加」"
                }
            }
        }
    }
'

使用说明

  1. 将脚本保存为对应格式文件(比如diff-parser.py或diff-parser.sh)
  2. Shell脚本需赋予执行权限:chmod +x diff-parser.sh
  3. 在Git仓库目录下运行脚本,即可得到VS Code风格的变更行数输出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 03:15:42