目的
pullしたときにコンフリクトが発生したときなどvimdiffを利用してコンフリクトを解消する
手順
1. 使いどころ
例えば以下のようにgit pullが失敗して手動でmergeする必要がでてきたときに利用します
$ git pull
~
Auto-merging aaa
CONFLICT (content): Merge conflict in aaa
Automatic merge failed; fix conflicts and then commit the result.
2. vimdiffをmergeツールとして利用するよう設定する
以下のようにglobalコンフィグに入れておく
$ git config --global merge.tool vimdiff
$ git config --global merge.conflictstyle diff3
$ git config --global mergetool.prompt false
入力せずともgit mergetoolの中でmerge toolに何を使うかきかれるのでvimiffとしておけばよい。
3. vimdiffを開く
$ git mergetool
このコマンドを入力すると以下のようなvimdiffの画面が開く
╔═══════╦══════╦════════╗
║ LOCAL ║ BASE ║ REMOTE ║
╠═══════╩══════╩════════╣
║ ║
║ MERGED ║
║ ║
╚═══════════════════════╝
ウィンドウ | 役割 |
---|---|
LOCAL | 現在のワーキングツリー上のファイル |
BASE | 共通の先祖ファイル。変更前はどのようなファイルだったか |
REMOTE | ワーキングツリーへマージしようとしているファイル |
MERGED | 最終的にレポジトリの中で保存されるファイル |
4. vimdiffの使い方
ウィンドウ間の移動
各ウィンドウ間は [ctrl]+w → hjklで移動できる(h:left, j:down, k:up, l:right)。
※hjklの代わりにカーソルでもOK
マージ方法
MERGEDウィンドウに移るとコンフリクト部分が色付きで表示されている
<<<<<<<<から>>>>>>>>の間がコンフリクト箇所
<<<<<<< HEAD
localfile
||||||| merged common ancestors
ancestor
=======
remotefile
>>>>>>> ap8990as3eipsaldjff669197e1sdkfasasdf1131d
コンフリクト箇所にカーソルを合わせたら、LOCAL,BASE,REMOTEどれを採用するかきめて以下のコマンドで反映させる。
採用対象 | 反映コマンド |
---|---|
LOCAL | :diffg L |
BASE | :diffg B |
REMOTE | :diffg R |
その他 | 手動で編集 |
マージ処理の終了
編集が完了したらwindowを閉じる。
:xa
で終了することで、MERGEDウィンドウの編集内容を保存しつつ全ウィンドウ一括で閉じることができる。
MERGEDウィンドウにカーソルがあたっているなら、:wで保存して、:qaで全ウィンドウ一括で閉じる。
(:wqaで一気に閉じることも可能だが、この場合LOCAL,BASE,REMOTEのファイルも全て保存され、レポジトリの中にuntrackedファイルが増えてしまう)
:xa
作業中に発生したuntrackedファイルの削除
vimdiffでのmerge処理完了後、コンフリクトが発生していたローカルファイルは拡張子.orig付きの別名で保存されている。
これらvimdiffにより保存されたバックアップファイルはレポジトリには不要なのでgit cleanを利用し削除する。
※誤って新規作成したファイルを一緒に削除してしまわないよう注意が必要
$ git clean -n
$ git clean -f
git cleanはstagedされていないファイルを削除する。-n はドライランオプション。
もし、特定のファイルだけ削除したい場合はファイルパスを指定する。
$ git clean -n %untracked_file_path%
$ git clean -f %untracked_file_path%