205

ブランチをgitのマスターにマージしたところ、下の画像でAutomatic merge failed; fix conflicts and then commit the result.実行git mergetoolされ、vimdiffが開きました。vimdiff の使い方がわかりません。ここにある各パネルの意味と、マージの競合を修正するにはどうすればよいですか?

ここに画像の説明を入力

4

3 に答える 3

170

4つのバッファーはすべて、同じファイルの異なるビューを提供します。左上のバッファー(LOCAL)は、ファイルがターゲットブランチでどのように表示されたか(マージ対象)です。右上のバッファ(REMOTE)は、ファイルがソースブランチ(マージ元)でどのように表示されたかを示します。中央のバッファー(BASE)は、2つの共通の祖先です(したがって、左右のバージョンが互いにどのように分岐しているかを比較できます)。

次の点で誤解されるかもしれません。マージの競合の原因は、両方のファイルがBASE以降ファイルの同じ部分を変更したことだと思います。LOCALは引用符をdoubleからsingleに変更し、REMOTEも同じ変更を加えましたが、背景値を色からURLに変更しました。(マージは、LOCALへのすべての変更がREMOTEにも存在することに気付くほど賢くないと思います。それは、LOCALがREMOTEと同じ場所でBASE以降に変更を加えたことを知っているだけです)。

いずれの場合も、下部のバッファには、実際に編集できるファイル(作業ディレクトリにあるファイル)が含まれています。好きな変更を加えることができます。vimは、自動マージでは処理できなかった領域である各トップビューとの違いを示しています。REMOTEの変更が必要ない場合は、LOCALから変更をプルします。ローカルの変更よりも変更を優先する場合は、REMOTEから変更をプルします。REMOTEとLOCALの両方が間違っていると思われる場合は、BASEからプルしてください。より良いアイデアがあれば、まったく違うことをしてください!結局、ここで行う変更は、実際にコミットされる変更です。

于 2013-02-15T23:36:31.023 に答える
10

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

GitHub アップストリーム.

そしてそれをインストールします:

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.pyRealView_LOCAL_15560.py
  • RealView_BASE_15560.pyRealView_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

大きなエディタ ウィンドウで簡単に編集できると思われる場合は、直接編集してください。

競合をマージするために直接ジャンプ

]cvimdiff 内の次の差分ポイントにジャンプする間、常にマージの競合が発生するとは限りません。

これを助けるために、私は私の中に持っています~/.vimrc

# Git Merge conflict
nnoremap <leader>gm /\v^\<\<\<\<\<\<\< \|\=\=\=\=\=\=\=$\|\>\>\>\>\>\>\> /<cr>

競合を直接見つけます。

git imerge

おそらく最良の選択肢は、vimdiff の使用をあきらめて、通常の vim + git imergeに頼ることです。vimdiff の学習曲線は厄介であり、最も必要な機能を実行しないためです。

于 2019-06-14T15:52:35.963 に答える