ブランチをgitのマスターにマージしたところ、下の画像でAutomatic merge failed; fix conflicts and then commit the result.
実行git mergetool
され、vimdiffが開きました。vimdiff の使い方がわかりません。ここにある各パネルの意味と、マージの競合を修正するにはどうすればよいですか?
3 に答える
4つのバッファーはすべて、同じファイルの異なるビューを提供します。左上のバッファー(LOCAL)は、ファイルがターゲットブランチでどのように表示されたか(マージ対象)です。右上のバッファ(REMOTE)は、ファイルがソースブランチ(マージ元)でどのように表示されたかを示します。中央のバッファー(BASE)は、2つの共通の祖先です(したがって、左右のバージョンが互いにどのように分岐しているかを比較できます)。
次の点で誤解されるかもしれません。マージの競合の原因は、両方のファイルがBASE以降ファイルの同じ部分を変更したことだと思います。LOCALは引用符をdoubleからsingleに変更し、REMOTEも同じ変更を加えましたが、背景値を色からURLに変更しました。(マージは、LOCALへのすべての変更がREMOTEにも存在することに気付くほど賢くないと思います。それは、LOCALがREMOTEと同じ場所でBASE以降に変更を加えたことを知っているだけです)。
いずれの場合も、下部のバッファには、実際に編集できるファイル(作業ディレクトリにあるファイル)が含まれています。好きな変更を加えることができます。vim
は、自動マージでは処理できなかった領域である各トップビューとの違いを示しています。REMOTEの変更が必要ない場合は、LOCALから変更をプルします。ローカルの変更よりも変更を優先する場合は、REMOTEから変更をプルします。REMOTEとLOCALの両方が間違っていると思われる場合は、BASEからプルしてください。より良いアイデアがあれば、まったく違うことをしてください!結局、ここで行う変更は、実際にコミットされる変更です。
vimdiff を置き換える究極のマージツール
これは冗談のようなものですが、vimdiff を試した後、私が vimmer として最終的に収束したものです。
マージの競合を解決するには、ほとんどの場合、次の情報を確認する必要があります。
- リモート
- ローカル
- 2 つの差分:
- デフベースリモート
- diff ベース ローカル
次に、両方を一緒にしようとします。
vimdiff は画面に BASE、LOCAL、REMOTE を表示します:
+--------------------------------+
| LOCAL | BASE | REMOTE |
+--------------------------------+
| MERGED |
+--------------------------------+
何度も右左右を見て、必要な2つの差分を明確に表示する方法がわかりません。
さらに、LOCAL と REMOTE は git マージの競合マーカーで既に表示されているため、それらを再度表示するツールからはあまり得がありません。
したがって、代わりに、欠落していた差分を実際に表示する独自の小さな「差分ツール」を作成しました。
~/bin/cirosantilli-mergetool
#!/usr/bin/env bash
BASE="$1"
LOCAL="$2"
REMOTE="$3"
diff --color -u "$BASE" "$LOCAL"
diff --color -u "$BASE" "$REMOTE"
exit 1
そしてそれをインストールします:
git config --global mergetool.cirosantilli-mergetool.cmd 'cirosantilli-mergetool $BASE $LOCAL $REMOTE'
git config --global mergetool.cirosantilli-mergetool.trustExitCode true
# If you want this to become your default mergetool.
#git config --global merge.tool 'cirosantilli-mergetool'
今、あなたがするとき:
git mergetool -t cirosantilli-mergetool
端末に必要な2つの差分が表示されます。たとえば、次のようなものです。
--- ./src/dev/arm/RealView_BASE_15560.py 2019-12-27 13:46:41.967021591 +0000
+++ ./src/dev/arm/RealView_LOCAL_15560.py 2019-12-27 13:46:41.979021479 +0000
@@ -994,7 +994,7 @@
def setupBootLoader(self, cur_sys, loc):
if not cur_sys.boot_loader:
- cur_sys.boot_loader = [ loc('boot_emm.arm64'), loc('boot_emm.arm') ]
+ cur_sys.boot_loader = [ loc('boot.arm64'), loc('boot.arm') ]
cur_sys.atags_addr = 0x8000000
cur_sys.load_offset = 0x80000000
@@ -1054,7 +1054,7 @@
]
def setupBootLoader(self, cur_sys, loc):
- cur_sys.boot_loader = [ loc('boot_emm_v2.arm64') ]
+ cur_sys.boot_loader = [ loc('boot_v2.arm64') ]
super(VExpress_GEM5_V2_Base,self).setupBootLoader(
cur_sys, loc)
--- ./src/dev/arm/RealView_BASE_15560.py 2019-12-27 13:46:41.967021591 +0000
+++ ./src/dev/arm/RealView_REMOTE_15560.py 2019-12-27 13:46:41.991021366 +0000
@@ -610,10 +610,10 @@
def attachIO(self, *args, **kwargs):
self._attach_io(self._off_chip_devices(), *args, **kwargs)
- def setupBootLoader(self, cur_sys, loc):
- cur_sys.boot_loader = loc('boot.arm')
- cur_sys.atags_addr = 0x100
- cur_sys.load_offset = 0
+ def setupBootLoader(self, cur_sys, boot_loader, atags_addr, load_offset):
+ cur_sys.boot_loader = boot_loader
+ cur_sys.atags_addr = atags_addr
+ cur_sys.load_offset = load_offset
したがって、ターミナルにダンプされた 2 つの diff をここで確認できます。
RealView_BASE_15560.py
対RealView_LOCAL_15560.py
RealView_BASE_15560.py
対RealView_REMOTE_15560.py
差分が大きい場合は、 tmux superpowersで検索します。
TODO: Nirvana を達成するために最後に残された方法は、競合するハンクの差分のみを表示する方法です。diff が大きいのに小さな塊だけが競合する場合、それを見つけるのが煩わしいからです。
はい、vimdiff が提供するいくつかのショートカットが失われますが、一般的に競合を解決するには、両方のバージョンから慎重にコピーして貼り付ける必要があります。これは、通常の vim セッション内で git 競合マーカーを使用して問題なく実行できます。
vimdiff
実行中のファイルの観察と比較
座って で完璧なセットアップを自動化する前にcirosantilli-mergetool
、必要な 2 つの diff を取得するためにこれを行っていました。
git mergetool
の実行中vimdiff
に、たとえば という名前のファイルに競合がある場合main.py
、git は各バージョンのファイルを次のように生成します。
main_BASE_1367.py
main_LOCAL_1367.py
main_REMOTE_1367.py
git mergetool の PIDと同じディレクトリにmain.py
あり1367
、したがって「ランダムな」整数です。
したがって、必要な差分を表示するには、最初に生成されたファイルを で見つけてから、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
、この情報は、何が起こっているのかをすばやく把握するのに大いに役立ちます!
また、mergetool の実行中でも、ファイルを開くことができます。
vim main.py
大きなエディタ ウィンドウで簡単に編集できると思われる場合は、直接編集してください。
競合をマージするために直接ジャンプ
]c
vimdiff 内の次の差分ポイントにジャンプする間、常にマージの競合が発生するとは限りません。
これを助けるために、私は私の中に持っています~/.vimrc
:
# Git Merge conflict
nnoremap <leader>gm /\v^\<\<\<\<\<\<\< \|\=\=\=\=\=\=\=$\|\>\>\>\>\>\>\> /<cr>
競合を直接見つけます。
git imerge
おそらく最良の選択肢は、vimdiff の使用をあきらめて、通常の vim + git imergeに頼ることです。vimdiff の学習曲線は厄介であり、最も必要な機能を実行しないためです。