従来のコードをリベースしていますが、スクリプト(通常はコードフォーマッタ)が原因で発生する多くの競合が見つかりました。変更は簡単で予測可能であるため、スクリプトを簡単に再実行してコードに変更を適用できます。これは通常、gitのdiffマーカーで囲まれた3つの同じ「スニペット」を残します。
3つの一致するフラグメントと違いマーカーを見つけて単一のフラグメントに変換するスクリプトをどのように作成しますか?
例:
git rebase
次を生成します。
<<<<<<< HEAD
ACA
BCB
||||||| parent of 0cfd85b8e3... Beautify.
AAA
BBB
=======
AAC
BBC
>>>>>>> 0cfd85b8e3... Beautify.
フォーマッタを再実行すると、次の結果が表示されます。
<<<<<<< HEAD
ACC
BCC
||||||| parent of 0cfd85b8e3... Beautify.
ACC
BCC
=======
ACC
BCC
>>>>>>> 0cfd85b8e3... Beautify.
私はそれを次のように変換したいと思います:
ACC
BCC
私はgrep(新しい行で苦労しました)とpcregrep(逆参照/キャプチャグループで苦労しました)を含む非常に多くのことを試しました。どんなアイデアがありますか?
ベストアンサー1
この問題に対してステートフル awk プログラムを使用すると、次のように明確にわかります。
awk '/^<<<<<<</ { state = 1; next }
/^=======/ { state = 2; next }
/^>>>>>>>/ { state = 0; next }
state == 0 || state == 2' data
foo
prolog
AAC
BBC
epilog
bar
これには以下がdata
含まれます。
foo
prolog
<<<<<<< HEAD
ACA
BCB
||||||| parent of 0cfd85b8e3... Beautify.
AAA
BBB
=======
AAC
BBC
>>>>>>> 0cfd85b8e3... Beautify.
epilog
bar
state == 0
まだ初期化されていない場合はtrueなので、最初はステータス0になります。state
私たちはそれを見ると状態1に切り替え<<<<<<
、それを見ると状態2に切り替え、そして終了=======
マーカーを見ると状態0に戻ります>>>>>>>
。とても簡単です。
初期状態0(衝突トークンの外側)または状態2(衝突トークンの最後の部分)にある場合にのみ行を印刷します。
すべての場合において、コマンドはnext
失敗動作が発生しないことを保証します。最後のケースだけが何も印刷するので、最初の3つのケースは何も印刷せず、競合マークを識別し、状態を変更する以外は何もしないことを知っています。したがって、どの状態であっても、衝突フラグは印刷されない。状態 2 から状態 0 に戻ると、誤って=======
or>>>>>>>
行は印刷されません。
最初のジョブでは印刷されていない状態1に切り替わるので、必ずしも必要ではありませんが、next
含めることは一貫性を保つのに最適です。また効率:衝突マーカーは相互に排他的です。=======
すでに検出されている場合はテストする必要があります<<<<<<<
。