如何让git-diff仅显示修改行而隐藏删除行?
问题描述
初始代码:
1: int a = 1; 2: int b = 2; 3: int c = 3; 4: int d = 4;
删除第2、3行,并将第1行修改为int a = 0;,修改后代码:
1: int a = 0; 2: int d = 4;
此时执行git diff,默认输出会包含被删除的第2、3行:
1: - int a = 1; 2: - int b = 2; 3: - int c = 3; 4: + int a = 0; 5: int d = 4;
希望git diff仅显示实际修改的行(去掉纯删除的int b = 2;和int c = 3;行),得到如下输出:
1: - int a = 1; 2: + int a = 0; 3: int d = 4;
编写脚本时需要这类仅保留核心修改行的diff结果,便于解析,询问是否可通过git-diff直接实现,若不能还有其他解决办法。
解决方案
一、git-diff无法直接实现
git diff没有内置参数可单独过滤掉无对应新增行的纯删除行,它的输出逻辑基于文件变更块,会完整展示所有行级变更及上下文,无法单独剔除这类纯删除行。
二、借助命令行工具过滤实现
可以结合git diff与文本处理工具(如awk、grep)实现需求,以下是几种可行方案:
方案1:精准保留修改行对与上下文
使用awk编写逻辑,区分“修改行的删除部分”和“纯删除行”,保留修改行对与上下文行:
git diff | awk ' BEGIN { prev_line = ""; in_modify_block = 0 } /^-/ { if (prev_line ~ /^\+/) { print prev_line; print $0; prev_line = ""; in_modify_block = 0 } else { prev_line = $0; in_modify_block = 1 } next } /^\+/ { if (in_modify_block) { print prev_line; print $0; prev_line = ""; in_modify_block = 0 } else { prev_line = $0 } next } { if (prev_line != "") { print prev_line; prev_line = "" } print $0 } END { if (prev_line != "") print prev_line } '
该脚本会:
- 保留成对的
-和+行(即被修改的行) - 丢弃无对应
+行的单独-行(纯删除行) - 保留所有上下文行(空格开头的行)
方案2:仅保留变更行(无上下文)
如果不需要上下文行,可先让git diff输出无上下文的精简格式,再提取变更行:
git diff --unified=0 | grep -E '^[-+]' || true
--unified=0参数会移除所有上下文行,仅显示变更行,grep则提取-和+开头的行。
内容的提问来源于stack exchange,提问作者Marc Quebrar Tan
相关产品推荐
相关产品推荐

