虽然不存在直接从 Git 执行此操作的能力(至少从 2.13.0 开始),但您可以通过解析统一差异自行执行此操作,前提是您对构成更改行的内容做出一些假设。
如果 N 个删除后 N 个添加 = N 个更改的行,那么这是一个基于 GNU awk 的解决方案,它只输出统一差异补丁中添加/删除/更改的行数:
BEGIN {
inhunk = 0
adds = 0
deletes = 0
changes = 0
hunk_adds = 0
hunk_deletes = 0
}
function calcChanges() {
delta = hunk_adds - hunk_deletes
changes += (hunk_deletes < hunk_adds ? hunk_deletes : hunk_adds)
adds += (delta > 0 ? delta : 0)
deletes += (delta < 0 ? -delta : 0)
hunk_adds = 0
hunk_deletes = 0
}
/^@@|^diff/ {
calcChanges()
inhunk = ($1 == "@@") ? 1 : 0
}
/^+/ {
if (inhunk) {
hunk_adds += 1
}
}
/^-/ {
if (inhunk) {
hunk_deletes += 1
}
}
/^ / {
if (inhunk && hunk_adds + hunk_deletes > 0) {
calcChanges()
}
}
END {
calcChanges()
print "Lines added: " adds
print "Lines deleted: " deletes
print "Lines changed: " changes
}
这个脚本会这样运行:
git diff ... | awk -f path/to/script.awk
Lines added: 1
Lines deleted: 11
Lines changed: 2
上面考虑了如果有 N 次删除紧跟在一个大块中的 N 次添加,则一组 N 行已更改。例如:
diff --git a/blah.txt b/blah.txt
index deadbeef..ba5eba11 100644
--- a/blah.txt
+++ b/blah.txt
@@ -1,4 +1,4 @@
context
-deleted line
-deleted line
+added line
+added line
context
... 计算 2 个更改的行。
diff --git a/blah.txt b/blah.txt
index deadbeef..ba5eba11 100644
--- a/blah.txt
+++ b/blah.txt
@@ -1,3 +1,4 @@
context
-deleted line
+added line
+added line
context
...计为 1 条更改的行和 1 条添加的行。
diff --git a/blah.txt b/blah.txt
index deadbeef..ba5eba11 100644
--- a/blah.txt
+++ b/blah.txt
@@ -1,4 +1,3 @@
context
-deleted line
-deleted line
+added line
context
...计为 1 个更改的行和 1 个删除的行。
最后,
diff --git a/blah.txt b/blah.txt
index deadbeef..ba5eba11 100644
--- a/blah.txt
+++ b/blah.txt
@@ -1,6 +1,6 @@
context
+added line
context
-deleted line
+added line
context
-deleted line
context
...算作 1 个添加行、1 个更改行和 1 个删除行。
可以扩展脚本以列出每个文件的这些统计信息,但我保持简单以显示总体思路。