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;
}
次のパッチは読みやすくなりますが、1行だけ必要です。
--- 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つは、「同じ行が存在し、その行の前後に行が追加および削除された場合に同じ行を変更することを検討すること」です。既存のパッチにこのルールを適用する独自のスクリプトを作成することもできますが、問題を解決するための既存のツールはありますか?
答え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
複雑な線が変わっていないことを伝えます。拡張バージョンでは、2つの間の違いを探したいかもしれません。
短くて孤独な共通行(または空白ではない数)のみを考慮するよう((.*\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()