如何使用vimdiff解决冲突?

Coo*_* Yo 142 git vim mergetool git-merge git-merge-conflict

我刚刚在git中将一个分支合并到了我的主人中,我得到了Automatic merge failed; fix conflicts and then commit the result.现在我跑了git mergetool,vimdiff打开了下面的图像.我不知道如何使用vimdiff.这里的每个小组意味着什么,我应该如何解决合并冲突?

在此输入图像描述

che*_*ner 130

所有四个缓冲区都提供同一文件的不同视图.左上角缓冲区(LOCAL)是文件在目标分支中的显示方式(您要合并的内容).右上角缓冲区(REMOTE)是文件在源分支(您要合并的位置)中的显示方式.中间缓冲区(BASE)是两者的共同祖先(因此您可以比较左右版本之间的分歧).

我可能在以下几点上弄错了.我认为合并冲突的根源是两个文件都改变了自BASE以来文件的相同部分; LOCAL已将引号从double更改为single,REMOTE也进行了相同的更改,但也将背景值从颜色更改为URL.(我认为合并不够聪明,不会注意到LOCAL的所有更改也存在于REMOTE中;它只知道LOCAL已经在REMOTE所在的相同位置进行了更改,因为它已经进行了更改.

在任何情况下,底部缓冲区都包含您可以实际编辑的文件 - 位于工作目录中的文件.你可以做任何你喜欢的改变; vim向您展示它与每个顶视图的区别,顶视图是自动合并无法处理的区域.如果您不想更改REMOTE,请从LOCAL拉出更改.如果您更喜欢LOCAL更改,请从REMOTE中拉出更改.如果您认为REMOTE和LOCAL都错误,请从BASE拉出.如果你有更好的主意,做一些完全不同的事情!最后,您在此处所做的更改将是实际提交的更改.

  • 为什么选择downvote?如果有什么事实不正确,请修理它,或者至少指出它. (7认同)
  • `:x`或`:w`(`:x`也退出)加'return'. (4认同)
  • Anders:如果您不熟悉如何使用`vim`,还可以使用其他合并工具. (4认同)
  • 快速问题如何在vim中保存? (3认同)
  • @AndersKitson,因为你在Mac OS X上,FileMerge是完美的,免费的,并附带XCode. (3认同)

Tim*_*mur 65

@Chepner的答案很棒,我想补充一些关于"我应该如何解决合并冲突"的部分问题.如果你在这种情况下研究如何实际使用vimdiff,它会在下面.


首先,要解决"中止一切"选项 - 如果你不想使用"vimdiff"并想要中止合并:按Esc,然后输入:qa!并点击Enter.(另请参阅如何退出Vim编辑器?).然后Git会问你合并是否完成,回复n.


如果你想使用vimdiff,这里有一些有用的快捷方式.这假设您了解Vim的基础知识(导航和插入/正常模式):

  • 导航到底部缓冲区(合并结果): Ctrl-W j
  • 使用j/ 导航到下一个差异k; 或者,更好地,分别使用] c[ c导航到下一个和上一个差异
  • 使用z o而在折叠打开它,如果你想看到更多的上下文
  • 对于每个差异,根据@Chepner的答案,您可以从本地,远程或基本版本获取代码版本,或者根据您的需要进行编辑和重做
    • 从本地版本获取它,使用 :diffget LO
    • 来自远程: :diffget RE
    • 从基地: :diffget BA
    • 或者,如果你想自己编辑,首先从本地/远程/基站获取一个版本,然后进入插入模式并编辑其余的
  • 完成后,保存合并结果,并退出所有窗口 :wqa
  • 通常,git会检测到合并已完成并完成合并提交

您可以在Internet上搜索其他vimdiff快捷方式.我发现这个例子很有用:https://gist.github.com/hyamamoto/7783966

  • 这应该被投票x1000次并被接受为更好的答案. (7认同)

Cir*_*四事件 10

取代 vimdiff 的终极合并工具

这有点诙谐,但这是我在尝试 vimdiff 后最终收敛为 vimmer 的东西。

要解决合并冲突,我几乎总是需要查看:

  • 偏僻的
  • 当地的
  • 两个差异:
    • 差异基础遥控器
    • 差异基础本地

然后尝试将它们放在一起。

虽然 vimdiff 确实在屏幕上显示了 BASE、LOCAL 和 REMOTE:

    +--------------------------------+
    | LOCAL  |     BASE     | REMOTE |
    +--------------------------------+
    |             MERGED             |
    +--------------------------------+
Run Code Online (Sandbox Code Playgroud)

我不知道如何使它清楚地显示我需要的这两个差异,除了从右向左向右向左看很多次之外。

此外, LOCAL 和 REMOTE 已经在 git merge 冲突标记中可见,所以我没有从再次显示它们的工具中获得那么多。

因此,我创建了自己的小“difftool”,它实际上显示了我缺少的差异:

~/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
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

现在,当你这样做时:

git mergetool -t cirosantilli-mergetool
Run Code Online (Sandbox Code Playgroud)

它显示了我在终端上想要的两个差异,例如:

--- ./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
Run Code Online (Sandbox Code Playgroud)

因此,您可以在此处看到转储到终端中的两个差异:

  • RealView_BASE_15560.py 对比 RealView_LOCAL_15560.py
  • RealView_BASE_15560.py 对比 RealView_REMOTE_15560.py

如果差异很大,我会搜索我的 tmux superpowers

TODO:为了实现 Nirvana,剩下的最后一件事将是一种仅显示冲突大块差异的方法。因为如果差异很大但只有很小的块冲突,找到它很烦人。

是的,您确实丢失了 vimdiff 提供的一些快捷方式,但通常解决冲突需要从两个版本中仔细复制粘贴,我可以在带有 git 冲突标记的普通 vim 会话中做得很好。

vimdiff运行时观察和比较文件

在我坐下来用 自动化我的完美设置之前cirosantilli-mergetool,这就是我为获得我需要的两个差异所做的事情。

git mergetool运行时vimdiff,如果名为 的文件存在冲突main.py,git 会为每个版本生成文件,命名为:

main_BASE_1367.py
main_LOCAL_1367.py
main_REMOTE_1367.py
Run Code Online (Sandbox Code Playgroud)

在与git mergetool 的 PIDmain.py所在的目录相同的目录中1367,因此是一个“随机”整数,如在:在 git 合并冲突中,生成的 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
Run Code Online (Sandbox Code Playgroud)

与 一起git mergetool,这些信息可以帮助很多人快速弄清楚发生了什么!

此外,即使在 mergetool 正在运行时,您也可以打开文件:

vim main.py
Run Code Online (Sandbox Code Playgroud)

如果您觉得使用更大的编辑器窗口会更容易,则直接并在那里编辑它。

直接跳转合并冲突

虽然]c跳转到 vimdiff 中的下一个差异点,但那里并不总是存在合并冲突。

为了帮助解决这个问题,我在我的~/.vimrc

# Git Merge conflict
nnoremap <leader>gm /\v^\<\<\<\<\<\<\< \|\=\=\=\=\=\=\=$\|\>\>\>\>\>\>\> /<cr>
Run Code Online (Sandbox Code Playgroud)

直接找到冲突。

混帐

也许最好的选择是放弃使用 vimdiff 并依赖常规的 vim + git imerge,其中提到:如何找出导致冲突的 Git 提交?因为 vimdiff 的学习曲线很烦人,而且它没有做我们最需要的功能。


归档时间:

查看次数:

51695 次

最近记录:

6 年,4 月 前