如何实现与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 "行已添加」" } } } } '
使用说明
- 将脚本保存为对应格式文件(比如
diff-parser.py或diff-parser.sh) - Shell脚本需赋予执行权限:
chmod +x diff-parser.sh - 在Git仓库目录下运行脚本,即可得到VS Code风格的变更行数输出
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

