Git はコードのマージを非常に得意としています。マージとはローカルで高速、そして柔軟に行えるものです。当然のことですが、異なるブランチから誰かがコンテンツをマージするたびにコンフリクトが発生します。コンフリクトを解決するには、主な変更点を把握して見抜かなければなりません。コンフリクトの解決は、時には多くの作業が必要になります。
開発者にはそれぞれ好みのコンフリクト解決方法があります。そのため同僚ライターのダン・スティーブンが以前、Questions for Confluence を使用して社内の人に質問していました。
返ってきた回答と洞察はアトラシアン社員だけではなく、もっと多くの人に役立つものでした。そこで私たちが Git コンフリクトを解決するさまざまな方法を以下に詳しく注釈付きで紹介します。皆さまの毎日のコーディング作業に役立つアイデアや方法がここで得られることを願います。
セットアップ一般のヒント
それでは Git を適切にセットアップしてマージができるように基本的な設定から始めていきましょう。
1. セットアップのヒント
コンフリクトが生じた場合、コマンドラインに「git mergetool」と入力するかビジュアルツールを使ってマージセッションを開始できます。お好みのコンフリクト解決ソフトで Git の設定をするには「.gitconfig」内で「merge.tool」変数を使用してください。たとえば、KDiff3 を使用しているユーザーは、「.gitconfig」merge セクションに以下のように記述すると良いでしょう。
[merge]
tool="kdiff3"
これは以下のコマンドラインを入力するのと同じです。
git config --global merge.tool kdiff3
2. コンフリクトマーカーに共通する祖先を表示する
共通の祖先も表示できるようにコンフリクトマーカーを改善するには、以下の設定をします (ロビン・ストッカーとヒュー・ギデンズに感謝)。
git config --global merge.conflictstyle diff3
この設定でマーカー ||||||| のある新しいセクションを追加してコンフリクトに注釈を付けています。これにより、問題の 2 ブランチの共通祖先であるコミットをコンフリクトしている行がどのように参照しているのかが分かります。
3. マージに「patience」アルゴリズムを使う
XML ファイルのような長いコンテンツにコンフリクトがある場合や 2 つのバージョンが分岐した場合など、もう一度以下のようにマージを試してください。
git merge --strategy-option=patience
patience アルゴリズムを使用すると、関数やタグの不適切な括弧を調整する助けになります。このアルゴリズムの詳細は、Stack Overflow の回答 でご参照頂けます。
4. 単一ファイルの履歴に関する情報が必要な場合
ファイルに起こったこと確認するために SourceTree などのビジュアルツールを使用する他には、以下が利用できます。
git log --merge --decorate --source -p path/to/file/you/care/about
コンフリクトを手動で解決する
マージに対する作業において 2 つの派閥が存在します。低レベルプロセスを使用してコンフリクトマーカーを手作業で操作する開発者、そしてビジュアルツールを好んで使用する開発者です。どちらも極めて効果的です。
5. サンプルプロセス
同僚数人が手動のプロセスをシェアしてくれました。例としてジェイソン・ヒンチの作業を挙げます。
-
まず手動でマージを行う。
git merge the/other/branch git status
-
ファイルがどのようにコンフリクトしているかを確認する。
-
コンフリクトしている各ファイルに対して以下を行う。
- 好きなエディタ (IntelliJ または vim など) でファイルを開く。
- コンフリクトマーカーで囲まれている各ブロック (“>>>>” と “<<<<“) を確認する。
- それが適切かどうか、記述した人の意図は何なのかを確認して、可能なら解決する。
-
コンフリクトマーカーが意味をなさない場合 (ファイルの変更が多い場合にはよくある)、以下を実行する。
git diff HEAD...the/other/branch -- path/to/conflicting/file git diff the/other/branch...HEAD -- path/to/conflicting/file
これでどちらの変更点が少ないか確認できる。
-
コマンド
git log -p HEAD..the/other/branch -- path/to/conflicting/file git log -p the/other/branch..HEAD -- path/to/conflicting/file
これらを使うことでそれぞれの変更点が明らかになることが多い。
-
変更点の一番多いファイルに戻す。
git checkout the/other/branch -- path/to/conflicting/file
(あるいは、git checkout --theirs または --ours を使っても良い)
-
手動で確認して、変更をもう一方のファイルに反映する。
git add path/to/conflicting/file
-
すべての変更を修正したらプロジェクトをビルドして、最低でもコンパイルをする。簡単にテストできる場合はテストも行う。
git commit
少し面倒に見えるかもしれませんが、ジェイソンのワークフローでは良くないマージが減少しました。
コンフリクトを手動で解決する方法を段階的に説明している基礎動画を、最新の Git Power Routines コースでご参照ください。
数々のマージツール
複雑なマージやコンフリクトの解決をするビジュアルツールがたくさんあります。私の同僚たちが幅広いツールを (完全に網羅しているわけではありませんが) 挙げていました。
6. IntelliJ IDEA コンフリクト解決ツール
IntelliJ IDEA はアトラシアンの多くの社員が利用している IDE です。コンフリクトに対処するために、多くの人がビルトインの IntelliJ IDEA コンフリクト解決ツールを使っています。このツールは分析用にローカル、リモート、マージ結果の 3 つのペインを用意しています。
7. KDiff3
KDiff3 は KDE プロダクトスイートの 1 つで、当社内の調査で数回言及されました。
8. P4Merge
SourceTree の最初の作者スティーブ・ストリーティングと数名の同僚は P4Merge をマージに使用しています。P4Merge は無料のビジュアルツールで、他のツールは 3 つですがこのツールは 4 つのペインを用意しています。このペインが表示するのは「ベース」「ローカル」「リモート」「マージ結果」です。
9. meld
meld はGTK+ と Python で開発されたツールで、長い間使用されていて、数人がこのツールを挙げました。
10. ステータス用の tig と diff
ターミナルが好きな人たちは tig (当社は 以前 tig に関する素晴らしい紹介記事 を書きました) と標準ターミナルの git diff を使用しています。
11. OS X FileMerge、別名 opendiff
多くの提案の中で、2、3 人の開発者が OS X のネイティブツール「opendiff」、あるいは「FileMerge」というツールを挙げました。
12. diffmerge
私は diffmerge についてあまり知りませんでしたが、これも提案の中にありました。
13. Araxis Merge (商用)
私はこの Araxis Merge という名前を見ると、ずっと以前に厳重な Windows マシンで作業していた頃を思い出します。大量の XML ファイルの中でもがき、このツールが役に立つことが分かりました。これは商用ツールです。
14. vimdiff3
数人の同僚が vimdiff を使用してコンフリクトを解決しています。これは vim のマージ / diff ツールです。以下のように入力して設定します。
git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false
あるいは .gitconfig ファイルを上記のように直接修正します。
まとめ
あなたはコンフリクトをどのように解決していますか? ここで挙げたツールとは違うツールを使用していますか? あなたのテクニックを教えてください。@durdn または、当社の素晴らしいチーム @atlassiandev までご連絡ください。
*本ブログは Atlassian Developers の翻訳です。本文中の日時などは投稿当時のものですのでご了承ください。
*原文 : 2015 年 12 月 1 日 "14 tips and tools to resolve conflicts with Git"