如何在 git 提交中识别并列出独特的帅哥?
How do I identify & list unique hunks in a git commit?
我有一个包含大量(数百个)类似 hunks 的提交,我想列出提交中的每个独特的大块以便比较它们。
我编写了以下 GNU awk 脚本,它将每个块写入一个唯一的文件 (hunk-[md5-of-hunk].txt
):
BEGIN {
hunk = ""
buildhunk = 0
}
function writeHunk() {
if (length(hunk) > 0) {
print hunk > "hunk.tmp"
close("hunk.tmp")
cmd = "cat hunk.tmp | md5"
cmd | getline md5
close(cmd)
if (!(md5 in hunkfiles)) {
hunkfilename = "hunk-" md5 ".txt"
print hunk > hunkfilename
hunkfiles[md5] = hunkfilename
}
}
}
/^@@|^diff/ {
writeHunk()
hunk = ""
buildhunk = ( == "@@") ? 1 : 0
}
/^[ +-]/ {
if (buildhunk) {
hunk = hunk [=11=] "\n"
}
}
END {
writeHunk()
system("rm hunk.tmp")
for (md5 in hunkfiles) {
print hunkfiles[md5]
}
}
然后我 运行 使用 git show [commit-SHA] | awk -f my_script.awk
这会创建并列出生成的文件。它适用于我的目的,但是有没有一种方法可以使用 git 的管道命令更有效地做到这一点。
例子
假设提交的补丁看起来像这样(为清楚起见,在下面减少了 1 行上下文):
diff --git a/file1.txt b/file1.txt
index a3fb2ed..4d6f587 100644
--- a/file1.txt
+++ b/file1.txt
@@ -3,2 +3,3 @@ context
context
+added line
context
@@ -7,2 +8,3 @@ context
context
+added line
context
@@ -11,2 +13,3 @@ context
context
+added line
context
@@ -15,2 +18,3 @@ context
context
+different added line
context
@@ -19,2 +23,3 @@ context
context
+different added line
context
@@ -23,2 +28,3 @@ context
context
+different added line
context
@@ -27,2 +33,3 @@ context
context
+even more different added line
context
@@ -31,2 +38,3 @@ context
context
+even more different added line
context
我希望能够识别只有 3 个独特的帅哥,并看看他们是什么。即:
独一无二的帅哥 1:
context
+added line
context
独一无二的帅哥 2:
context
+different added line
context
独一无二的帅哥 3:
context
+even more different added line
context
提交是快照,因此,它们没有 diff hunks。
差异,当然,确实有差异大块头。因此,如果您只有一次提交,则根本无法执行此操作。您需要 两次 次提交。然后你只需简单地区分它们并做你正在做的事情。
请注意 git show <commit-hash>
的实际意思是 git diff <parent or parents of commit> <commit-hash>
。如果指定的提交是合并提交,这会产生一个 组合差异 ,这可能对您的目的没有用,因为组合差异有意完全忽略许多更改。您可能希望 运行 仅针对提交的 first 父项进行显式差异(仅查看作为合并的一部分引入的更改)。
对于 git rerere
和 git patch-id
,Git 的某些部分在内部执行与您正在执行的操作类似的操作。但是,他们不会完全你正在做的事情:对于rerere
,他们只记录存在合并冲突的差异块,并匹配那些差异块(已保存通过哈希 ID 和文件名),稍后记录解决方案。对于 patch-id
他们去掉了行号和 white-space 但将提交中的整组更改累积成一个大块。如果 Git 有一些管道可以一个接一个地完成 git patch-id
部分,独立于计算提交的整体补丁 ID,但它没有。
我有一个包含大量(数百个)类似 hunks 的提交,我想列出提交中的每个独特的大块以便比较它们。
我编写了以下 GNU awk 脚本,它将每个块写入一个唯一的文件 (hunk-[md5-of-hunk].txt
):
BEGIN {
hunk = ""
buildhunk = 0
}
function writeHunk() {
if (length(hunk) > 0) {
print hunk > "hunk.tmp"
close("hunk.tmp")
cmd = "cat hunk.tmp | md5"
cmd | getline md5
close(cmd)
if (!(md5 in hunkfiles)) {
hunkfilename = "hunk-" md5 ".txt"
print hunk > hunkfilename
hunkfiles[md5] = hunkfilename
}
}
}
/^@@|^diff/ {
writeHunk()
hunk = ""
buildhunk = ( == "@@") ? 1 : 0
}
/^[ +-]/ {
if (buildhunk) {
hunk = hunk [=11=] "\n"
}
}
END {
writeHunk()
system("rm hunk.tmp")
for (md5 in hunkfiles) {
print hunkfiles[md5]
}
}
然后我 运行 使用 git show [commit-SHA] | awk -f my_script.awk
这会创建并列出生成的文件。它适用于我的目的,但是有没有一种方法可以使用 git 的管道命令更有效地做到这一点。
例子
假设提交的补丁看起来像这样(为清楚起见,在下面减少了 1 行上下文):
diff --git a/file1.txt b/file1.txt
index a3fb2ed..4d6f587 100644
--- a/file1.txt
+++ b/file1.txt
@@ -3,2 +3,3 @@ context
context
+added line
context
@@ -7,2 +8,3 @@ context
context
+added line
context
@@ -11,2 +13,3 @@ context
context
+added line
context
@@ -15,2 +18,3 @@ context
context
+different added line
context
@@ -19,2 +23,3 @@ context
context
+different added line
context
@@ -23,2 +28,3 @@ context
context
+different added line
context
@@ -27,2 +33,3 @@ context
context
+even more different added line
context
@@ -31,2 +38,3 @@ context
context
+even more different added line
context
我希望能够识别只有 3 个独特的帅哥,并看看他们是什么。即:
独一无二的帅哥 1:
context
+added line
context
独一无二的帅哥 2:
context
+different added line
context
独一无二的帅哥 3:
context
+even more different added line
context
提交是快照,因此,它们没有 diff hunks。
差异,当然,确实有差异大块头。因此,如果您只有一次提交,则根本无法执行此操作。您需要 两次 次提交。然后你只需简单地区分它们并做你正在做的事情。
请注意 git show <commit-hash>
的实际意思是 git diff <parent or parents of commit> <commit-hash>
。如果指定的提交是合并提交,这会产生一个 组合差异 ,这可能对您的目的没有用,因为组合差异有意完全忽略许多更改。您可能希望 运行 仅针对提交的 first 父项进行显式差异(仅查看作为合并的一部分引入的更改)。
对于 git rerere
和 git patch-id
,Git 的某些部分在内部执行与您正在执行的操作类似的操作。但是,他们不会完全你正在做的事情:对于rerere
,他们只记录存在合并冲突的差异块,并匹配那些差异块(已保存通过哈希 ID 和文件名),稍后记录解决方案。对于 patch-id
他们去掉了行号和 white-space 但将提交中的整组更改累积成一个大块。如果 Git 有一些管道可以一个接一个地完成 git patch-id
部分,独立于计算提交的整体补丁 ID,但它没有。