1. ホーム
  2. git

[解決済み] gitのdifftoolとmergetoolとしてMeldをセットアップして使用する

2022-03-17 18:35:53

質問

このQ&Aで紹介されている情報の多くは スタックオーバーフロー しかし、それは多くのページに分散し、間違っているか誤解を招くような他の答えの中にあります。私が知りたいことをすべてまとめるのに時間がかかりました。

git の difftool や mergetool として使用できるプログラムにはさまざまなものがあり、どれが一番適しているかというコンセンサスは得られていないようです。 ベスト (意見、要件、OSは明らかに異なるでしょう)。

Meldは、フリー、オープンソース、クロスプラットフォーム(UNIX/Linux、OSX、Windows)の選択肢として、以下のように人気があります。 スタックオーバーフロー という質問をします。 Git 用のビジュアルマージツールで一番いいのは何ですか? その中で、Meldを提案する回答は他のツールの3倍以上の票を獲得しています。

以下の2つの質問は、以下の私の回答でお答えします。

  • git difftoolとしてMeldを設定し、使用するにはどうすればよいですか?
  • git mergetoolとしてMeldをセットアップして使用するにはどうしたらいいですか?

注意:difftoolとmergetoolの両方に同じプログラムを使用する必要はなく、両方に異なるプログラムを設定することができます。

解決方法は?

git difftoolとしてMeldをセットアップして使用するにはどうしたらいいですか?

git difftool は、ターミナルに diff の出力を表示する代わりに、GUI の diff プログラム (Meld など) を使用して diff を表示します。

GUIプログラムの設定は、コマンドラインから -t <tool> / --tool=<tool> で設定する方がより理にかなっています。 .gitconfig ファイルを作成します。[注意: 最下部の引用符のエスケープとWindowsパスについてのセクションを参照してください] 。

# Add the following to your .gitconfig file.
[diff]
    tool = meld
[difftool]
    prompt = false
[difftool "meld"]
    cmd = meld "$LOCAL" "$REMOTE"

[注:これらの設定によって git diff これは通常通り機能します] 。

あなたは git difftool を使うのと全く同じように git diff ... 例

git difftool <COMMIT_HASH> file_name
git difftool <BRANCH_NAME> file_name
git difftool <COMMIT_HASH_1> <COMMIT_HASH_2> file_name

正しく設定された場合、Meld ウィンドウが開き、GUI インターフェイスで diff が表示されます。

Meld GUIウィンドウペインの順序は、以下の順序で制御できます。 $LOCAL$REMOTEcmd つまり、どのファイルを左ペインに、どのファイルを右ペインに表示するかということです。逆にしたい場合は、このように入れ替えるだけです。

    cmd = meld "$REMOTE" "$LOCAL"

最後に prompt = false の行は、Meld を起動するかどうかのプロンプトを表示しないようにするだけです。


git mergetoolとしてMeldをセットアップして使用するにはどうしたらいいですか?

git mergetool を使用すると、マージ中に発生したマージの競合を解決するために GUI マージプログラム (例: Meld) を使用することができます。

difftool のように、GUI プログラムをコマンドラインで設定するには、次のようにします。 -t <tool> / --tool=<tool> しかし、以前と同じように、この設定は .gitconfig ファイルを作成します。[注意: 最下部の引用符のエスケープとWindowsのパスについてのセクションを参照してください] 。

# Add the following to your .gitconfig file.
[merge]
    tool = meld
[mergetool "meld"]
    # Choose one of these 2 lines (not both!) explained below.
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"
    cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"

は使用しないでください。 git mergetool を使用して、実際のマージを実行します。を使用する前に git mergetool の場合は、通常の git の操作でマージを行います。

git checkout master
git merge branch_name

マージの競合がある場合、gitはこのように表示します。

$ git merge branch_name
Auto-merging file_name
CONFLICT (content): Merge conflict in file_name
Automatic merge failed; fix conflicts and then commit the result.

この時点で file_name は、マージ競合情報を含む部分的にマージされたファイル (これは、すべての >>>>>>><<<<<<< のエントリーがあります)。

Mergetool は、マージの競合を解決するために使用できます。で非常に簡単に開始できます。

git mergetool

正しく設定された場合、Meldウィンドウが開き、3つのファイルが表示されます。各ファイルは、そのGUIインタフェースの別のペインに含まれます。

この例では .gitconfig のエントリでは、2行が提案されています。 [mergetool "meld"] cmd という行があります。実際には、上級者向けのあらゆる方法で cmd という行がありますが、それはこの回答の範囲外です。

この回答には2つの選択肢があります。 cmd の行は、ほとんどのユーザーに対応でき、次のレベルの複雑なツールを使いたい上級ユーザーにとっては良い出発点となるでしょう。

まず最初にパラメータの意味を説明します。

  • $LOCAL は、現在のブランチ (例: master) にあるファイルです。
  • $REMOTE は、マージされるブランチのファイルです (例: branch_name)。
  • $MERGED は、マージの競合情報を含む部分的にマージされたファイルです。
  • $BASE の共有コミット先祖です。 $LOCAL$REMOTE を含むブランチが存在するときのファイルということになります。 $REMOTE が作成されました。

どちらかを使うことをお勧めします。

[mergetool "meld"]
    cmd = meld "$LOCAL" "$MERGED" "$REMOTE" --output "$MERGED"

または

[mergetool "meld"]
    cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"
    # See 'Note On Output File' which explains --output "$MERGED".

を使うかどうかの選択です。 $MERGED または $BASE の間に $LOCAL$REMOTE .

どちらの方法でも、Meldは3つのペインに $LOCAL$REMOTE を左右のペインに、どちらかを $MERGED または $BASE を中央のペインに表示します。

どちらの場合も、中央のペインが、マージの競合を解決するために編集すべきファイルです。違いは、どちらの編集開始位置を選ぶかだけです。 $MERGED は、部分的にマージされたファイルとマージされたコンフリクトの情報を含むファイル、または $BASE の共有コミット先祖の場合 $LOCAL$REMOTE . [どちらも cmd の行は有用であるため、私は両方の行を自分の .gitconfig ファイルを作成します。ほとんどの場合、私は $MERGED の行と $BASE の行はコメントアウトされていますが、このコメントアウトは、もし私が $BASE の行で代用しています]。

出力ファイルに関する注意事項 --output "$MERGED" が使われているのは cmd に関係なく $MERGED または $BASE は、先に使用した cmd の行になります。その --output オプションは、gitがコンフリクト解消ファイルをどのようなファイル名で保存したいかをMeldに伝えるだけのものです。を使うかどうかにかかわらず、Meldはコンフリクトの編集をそのファイルに保存します。 $MERGED または $BASE を編集の起点とします。

真ん中のペインを編集してマージの競合を解決したら、ファイルを保存してMeldウィンドウを閉じればよいのです。Git は自動的に更新を行い、現在のブランチ (例: master) にあるファイルには、中央のペインで最終的に作成したものが含まれるようになります。

git は、部分的にマージしたファイルのバックアップにマージ時の衝突情報を付加しています。 .orig を元のファイル名に追加します。 file_name.orig . マージに問題がないことを確認し、必要なテストを実行した後、次のように .orig ファイルを削除することができます。

この時点で、変更をコミットするためにcommitを実行することができます。

Meldでマージコンフリクトを編集しているときに、Meldの使用をやめたい場合は、中央ペインのマージ解決ファイルを保存せずにMeldを終了してください。 file_name seems unchanged と問いかけ、その後に Was the merge successful? [y/n] と答えた場合 n の場合、マージの競合の解決は中止され、ファイルは変更されないままです。Meld でファイルを保存している場合は、git からの警告やプロンプトは表示されないことに注意しましょう。[もちろん、そのファイルを削除してバックアップファイルと置き換えることもできます。 .orig ファイルを作成しました]。

マージが競合するファイルが複数ある場合、git はそれぞれのファイルに対して新しい Meld ウィンドウを開き、それらがすべて完了するまで次々に表示します。すべて同時に開かれるわけではありませんが、1つのファイルのコンフリクトの編集を終えてMeldを閉じると、gitは次のウィンドウを開き、すべてのマージコンフリクトが解決されるまでそれを繰り返します。

の使い方をテストするために、ダミーのプロジェクトを作成するのが賢明でしょう。 git mergetool で使用する前に 生きる プロジェクトに参加します。テストでは、必ずスペースを含むファイル名を使用してください。 cmd の行を参照してください。


引用符のエスケープ

オペレーティングシステムによっては、引用符で囲む必要があります。 cmd をエスケープします。経験の浅いユーザは、config コマンドラインがスペースを含むファイル名でテストされることを覚えておいてください。 cmd の行は、スペースを含むファイル名で動作しない場合、引用符をエスケープしてみてください。

cmd = meld \"$LOCAL\" \"$REMOTE\"

場合によっては、より複雑な引用符のエスケープが必要になることがあります。以下のWindowsパスのリンクの1つ目は、各引用符をトリプルエスケープする例を含んでいます。これは面倒ですが、時には必要です。

cmd = meld \\\"$LOCAL\\\" \\\"$REMOTE\\\"

Windowsのパス

Windows ユーザーは、Meld に追加された設定が必要になることがあります。 cmd の行があります。へのフルパスが必要な場合があります。 meldc これは Windows でコマンドラインから呼び出すように設計されていますが、ラッパーを使用する必要があるかもしれません。を読む必要があります。 スタックオーバーフロー のページでは、正しいMeldの設定について説明しています。 cmd の行をWindows用に変更しました。私はLinuxユーザーなので、Windowsの様々な cmd の行を追加し、Meldへのフルパスを追加した私の例を使用することをお勧めする以外には、この件に関する詳細な情報はありません。 meldc または、Meldのプログラムフォルダを path .

Meldで末尾の空白を無視する

Meldには、GUIで設定可能ないくつかのプリファレンスがあります。

プリファレンスでは Text Filters タブには、diff を実行する際にコメントなどを無視するための便利なフィルタがいくつか用意されています。を無視するフィルタがありますが All whitespaceLeading whitespace を無視することはできません。 Trailing whitespace フィルタが追加されました (これはMeldメーリングリストに提案されましたが、私のバージョンでは使用できません)。

末尾の空白を無視することは、特に共同作業をする際に非常に便利で、Meldの環境設定で簡単な正規表現を使用して手動で簡単に追加できます。 Text Filters タブに表示されます。

# Use either of these regexes depending on how comprehensive you want it to be.
[ \t]*$
[ \t\r\f\v]*$


皆さんのお役に立てれば幸いです。