Gitでマスターにブランチをマージしたところ、Automatic merge failed; fix conflicts and then commit the result.
になったので、git mergetool
を実行し、以下の画像でvimdiffを開きました。 vimdiffの使用方法がわかりません。ここの各パネルの意味と、マージの競合を修正するにはどうすればよいですか?
4つのバッファはすべて、同じファイルの異なるビューを提供します。左上のバッファ(LOCAL)は、ターゲットブランチでのファイルの外観(マージ先)です。右上のバッファ(REMOTE)は、ソースブランチ(マージ元)でのファイルの外観です。中間バッファー(BASE)は、2つの共通の祖先です(したがって、左右のバージョンが互いにどのように分岐したかを比較できます)。
次の点で誤解される可能性があります。マージの競合の原因は、両方のファイルがBASE以降にファイルの同じ部分を変更したことです。 LOCALは引用符をdoubleからsingleに変更し、REMOTEは同じ変更を加えましたが、背景値も色からURLに変更しました。 (マージは、LOCALへのすべての変更がREMOTEにも存在することに気付くほどスマートではないと思います。LOCALがREMOTEと同じ場所でBASEから変更を加えたことを知っているだけです)。
いずれにせよ、一番下のバッファには実際に編集できるファイルが含まれています。これは作業ディレクトリにあるファイルです。好きなように変更できます。 vim
は、トップビューのそれぞれとの違いを示しています。トップビューは、自動マージでは処理できなかった領域です。リモートの変更が必要ない場合は、ローカルから変更をプルします。ローカルの変更よりも必要な場合は、リモートから変更をプルします。 REMOTEとLOCALの両方が間違っていると思われる場合は、BASEからプルします。より良いアイデアがあれば、まったく違うことをしてください!最終的に、ここで行う変更は、実際にコミットされるものです。
@chepnerの答えは素晴らしいです。質問の「マージの競合を修正するにはどうすればよいか」という部分に詳細を追加したいと思います。この場合にvimdiffを実際に使用する方法を調べると、以下になります。
まず、「すべてを中止する」オプションに対処する-「vimdiff」を使用せずにマージを中止する場合:を押します Esc、次に:qa!
と入力してヒット Enter。 ( Vimエディターを終了するにはどうすればよいですか? も参照)。 Gitは、マージが完了したかどうかを尋ねます。n
で返信します。
Vimdiffを使用する場合の便利なショートカットを次に示します。これは、Vimの基本(ナビゲーションと挿入/通常モード)を知っていることを前提としています。
:diffget LO
を使用します:diffget RE
:diffget BA
:wqa
:cquit
で終了します: 外部git diffをキャンセルするにはどうすればよいですか?コピーペーストまたはカスタムショートカットなしでローカルおよびリモートの競合ハンクを追加することはできないようです: https://vi.stackexchange.com/questions/10534/is-there-a -way-to-take-both-when-using-vim-as-merge-tool これは、add addが一般的な競合タイプであるため残念です。
Vimdiffが起動するたびにEnterキーを押すように要求しないようにするには、.vimrc
に追加します。
set shortmess=Ot
他のvimdiffショートカットをインターネットで検索できます。私はこれが便利だとわかりました: https://Gist.github.com/hyamamoto/7783966
vim -d
を使用して(BASEとLOCAL)と(BASEとREMOTE)を比較する方法
マージの競合を解決するとき、最も重要なことの1つは次のとおりです。
次に、両方を一緒にしようとします。
vimdiff
はBASE、LOCAL、REMOTEのすべてを並べて表示するのに適していますが、BASEからの2つの個別の差分を明確に見ることはできません。
+--------------------------------+
| LOCAL | BASE | REMOTE |
+--------------------------------+
| MERGED |
+--------------------------------+
これを解決するために、git mergetool
がvimdiff
を実行しているときに、たとえばmain.py
という名前のファイルに競合がある場合、gitは次の名前の各バージョンのファイルを生成することに気付きました。
main_BASE_1367.py
main_LOCAL_1367.py
main_REMOTE_1367.py
main.py
と同じディレクトリにあり、1367
はgit mergetoolのPIDです。したがって、次のように「ランダムな」整数です。 git merge conflictでは、BACKUP、BASE、LOCAL、REMOTE生成されますか?
だから、私が欲しい差分を見るために、最初にgit status
で生成されたファイルを見つけ、次に新しいターミナルを開いて、気にするファイルのペアの間でvimdiffを実行します:
vim -d main_BASE_1367.py main_LOCAL_1367.py
vim -d main_BASE_1367.py main_REMOTE_1367.py
git mergetool
とともに、この情報はA LOTが迅速に何が起こっているかを把握するのに役立ちます!
また、mergetoolの実行中であっても、ファイルを開くことができます。
vim main.py
エディタウィンドウを大きくすれば簡単になると思われる場合は、直接編集してください。
これらすべてのファイルを自動的に開くために、さらに自動化できると思いますが、私はまだそこに挑戦していません。
衝突をマージするために直接ジャンプする
]c
はvimdiff内の次のdiffポイントにジャンプしますが、マージの競合が常に存在するとは限りません。
これを支援するために、私は~/.vimrc
にあります:
# Git Merge conflict
nnoremap <leader>gm /\v^\<\<\<\<\<\<\< \|\=\=\=\=\=\=\=$\|\>\>\>\>\>\>\> /<cr>
競合を直接見つけます。