たとえば、gitとdiff3で重複する複数行グループを置き換える方法

たとえば、gitとdiff3で重複する複数行グループを置き換える方法

従来のコードをリベースしていますが、スクリプト(通常はコードフォーマッタ)が原因で発生する多くの競合が見つかりました。変更は簡単で予測可能であるため、スクリプトを簡単に再実行してコードに変更を適用できます。これは通常、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含めることは一貫性を保つのに最適です。また効率:衝突マーカーは相互に排他的です。=======すでに検出されている場合はテストする必要があります<<<<<<<

おすすめ記事