C 함수를 처음부터 다시 작성한다고 가정해 보겠습니다. 일부 줄, 특히 빈 줄과 닫는 중괄호가 앞뒤로 정확히 동일한 경우가 종종 발생합니다. 통합 diff( 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
다음 스크립트는 diff에서 "거의 완전히 다른" 시퀀스를 감지하고 이를 완전히 다른 것으로 처리하여 상황을 개선했습니다. 더 나은 솔루션을 찾으세요.
#!/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()