假设我从头开始重写了一个 C 函数。经常会发生某些行前后完全相同的情况,特别是空行和右大括号。当我创建统一的差异(使用git diff
或普通 GNU diff -u
)时,这些相同的行将大块分开,使审阅者更难阅读补丁。 Diff 想要产生最小差异的野心有时会牺牲可读性,这不是我想要的。有没有办法让 diff 牺牲最小性来让大块头保持在一起?
示例:考虑这个,由 diff 生成:
--- A 2018-10-01 09:37:37.606642955 +0200
+++ B 2018-10-01 09:37:40.405675295 +0200
@@ -1,6 +1,9 @@
int fib(int n) {
- if (n <= 1) {
- return n;
+ int i, t1 = 0, t2 = 1;
+ for (i = 0; i < n; ++i) {
+ int next = t1 + t2;
+ t1 = t2;
+ t2 = next;
}
- return fib(n-1) + fib(n-2);
+ return t1;
}
在我看来,以下等效补丁会更容易阅读,但只需多一行:
--- A 2018-10-01 09:37:37.606642955 +0200
+++ B 2018-10-01 09:37:40.405675295 +0200
@@ -1,6 +1,9 @@
int fib(int n) {
- if (n <= 1) {
- return n;
- }
- return fib(n-1) + fib(n-2);
+ int i, t1 = 0, t2 = 1;
+ for (i = 0; i < n; ++i) {
+ int next = t1 + t2;
+ t1 = t2;
+ t2 = next;
+ }
+ return t1;
}
因此,一种可能的启发是“如果存在相同的行,并且在该行之前和之后都添加和删除了行,则考虑更改相同的行”。我当然可以创建自己的脚本,在现有补丁上应用此规则,但是是否有现有工具可以解决我的问题?
答案1
您可以通过将diff -u
输出传送到以下位置来实现您的方法:
perl -0777 -pe '1 while s{^-.*\n\K((?:\+.*\n)+) ((.*\n)(?:-.*\n)+)}
{-$2$1+$3}mg'
现在我不相信不显示孤独的共同线总是有助于提高可读性。比较一下例如:
--- A 2018-10-01 09:37:37.606642955 +0200
+++ B 2018-10-01 09:37:40.405675295 +0200
@@ -1,8 +1,11 @@
int fib(int n) {
- if (n <= 1) {
- return n;
+ int i, t1 = 0, t2 = 1;
+ for (i = 0; i < n; ++i) {
+ int next = t1 + t2;
+ t1 = t2;
+ t2 = next;
}
- /* assinging foo */
+ /* assigning foo */
foo = (bar ? bar : complicated_stuff(*a.asd.qwe|(FLAG1|FLAG2)));
- return fib(n-1) + fib(n-2);
+ return t1;
perl
上面有代码的输出:
--- A 2018-10-01 09:37:37.606642955 +0200
+++ B 2018-10-01 09:37:40.405675295 +0200
@@ -1,8 +1,11 @@
int fib(int n) {
- if (n <= 1) {
- return n;
- }
- /* assinging foo */
- foo = (bar ? bar : complicated_stuff(*a.asd.qwe|(FLAG1|FLAG2)));
- return fib(n-1) + fib(n-2);
+ int i, t1 = 0, t2 = 1;
+ for (i = 0; i < n; ++i) {
+ int next = t1 + t2;
+ t1 = t2;
+ t2 = next;
+ }
+ /* assigning foo */
+ foo = (bar ? bar : complicated_stuff(*a.asd.qwe|(FLAG1|FLAG2)));
+ return t1;
我发现它更有用,它diff
告诉我那条复杂的线没有改变。在扩展版本中,您可能会想寻找两者之间的差异。
您可以将 替换为 ,((.*\n)
以((.{0,20}\n)
仅考虑短的孤独的公共行(或(((?:\h*\H){0,10}\h*\n)
仅考虑非空白的数量)。
答案2
以下脚本通过检测差异中的“几乎完全不同”的序列并将它们视为完全不同来改善我的情况。寻找更好的解决方案。
#!/usr/bin/python
import sys
(mbefore, pbefore, mid, mafter) = ([], [], [], [])
def flush():
for x in (mbefore, pbefore, mid, mafter):
sys.stdout.write(''.join(x))
del x[:]
for line in sys.stdin:
if line[0] == '-':
if mid:
mafter.append(line)
else:
flush()
mbefore.append(line)
elif line[0] == '+':
if mafter:
mbefore.append('-' + mid[0][1:])
pbefore.append('+' + mid[0][1:])
mbefore += mafter
pbefore.append(line)
del mafter[:]
del mid[:]
elif not mid and mbefore:
pbefore.append(line)
else:
flush()
sys.stdout.write(line)
elif line[0] == ' ':
if pbefore and not mid:
mid.append(line)
else:
flush()
sys.stdout.write(line)
else:
flush()
sys.stdout.write(line)
flush()