使用 vimdiff 合并更改

在我的示例中,有两个文件 file1和 file2。使用 vimdiff,我想合并这些更改如下:

  1. 在第一个区别中,将 file1中的行放在 file2中的行上面。它意味着差异,如文件2中的 Listing 2和合并文件中的 List 2应该是 List 2后面跟着 Listing 2
  2. 另一个变化的反例。

下面显示了快照。

enter image description here

我们如何使用 Vimdiff 实现这一点?

72847 次浏览

您可以使用 Ctrlww在两个窗口之间来回切换。可以从一个窗口复制一个 Ctrlww,然后粘贴到另一个窗口。当您解决差异时,突出显示将改变并消失。

看看这个 视频

你可以在窗口之间切换,复制粘贴来解决这些差异,就像@David W. 在他的回答中建议的那样,但是 Vim 也专门使用了 :diffput:diffget命令来简化这个过程。使用这些命令(或相应的普通模式 dodp命令) ,您不必在窗口之间切换,并且范围默认为当前更改。

如果您需要 而不是覆盖与其他缓冲区的差异(这是一个相当不寻常的情况下,在一个典型的双向差异) ,您仍然必须 美国佬的原始行和 放下之后的 :diffget

在一个地方完成后,可以使用 ]c[c命令跳转到下一个差异。

可以使用以下基本命令进行合并:

  • do-获取从其他窗口到当前窗口的更改。

  • dp-将当前窗口的更改放到另一个窗口中。

  • 跳转到下一个更改。

  • 跳转到以前的更改。

  • 打开折叠线。

  • 关闭折叠线。

  • 完全展开两个文件。

  • 完全折叠两个文件。

  • 更改窗口。

  • 退出其他窗口,写入并退出。

需要注意的怪癖

  • dodp都可以工作,如果您处于正常模式下的一个更改块(或者只是一行更改下的一行) ,但不是在可视化模式下。

  • 撤消命令只能在已更改的缓冲区中工作,因此如果您使用 dp并更改了主意,则需要切换到另一个缓冲区以撤消。

  • :diffupdate将重新扫描文件以进行更改(Vim 可能会混淆,并显示伪造的内容)。

视觉模式与细粒度控制

在可视化模式下选择文本行时,必须使用普通命令:

  • :'<,'>diffget
  • :'<,'>diffput.

例如:

  1. 进入可视化模式并标记一些文本/行。
  2. 然后键入 :diffput将选定的行推送到另一个文件,或者键入 :diffget从另一个文件获取选定的行。

这意味着,如果有一个由多行组成的更改块,那么选择一个行子集并发出 :diffput将只应用另一个缓冲区中的那些更改。

(:diffget:diffput也接受范围,详情请参阅 :h copy-diffs。)

比较 Vim 中的两个缓冲区

如果以分割方式加载两个文件(:vs:sp) ,则可以在每个窗口上执行 :diffthis,并实现已经加载到缓冲区中的文件的差异。

:diffoff可以用来关闭差分模式。

这个 Vimcast 帖子和视频 在实践中展示了这一点。

如何应用缓冲区之间的所有更改

  1. 确保所有参与的缓冲区都处于 diff 模式(参见 :h start-vimdiff)

  2. 获取从缓冲区到当前缓冲区的更改: :%diffget <buffer-number>

  3. 将当前缓冲区的所有更改放入另一个缓冲区: :%diffput <buffer-number>

(:%是选择整个文件的范围; 请参阅 :h :%:ls将显示当前打开的缓冲区。)

我使用以下映射来处理三向合并(当 conflictstyle=diff3时)

  nnoremap g1 :<C-U>call MergeKeepLeft()<CR>
nnoremap g2 :<C-U>call MergeKeepBoth()<CR>
nnoremap g3 :<C-U>call MergeKeepRight()<CR>


function! MergeKeepLeft()
let lastsearch = @/
let @/ = '<<<<<<<'
execute "normal! ?\<cr>dd"


let @/ = '|||||||'
execute "normal! /\<cr>V"


let @/ = '>>>>>>>'
execute "normal! /\<cr>d"


let @/ = lastsearch
endfunction


function! MergeKeepBoth()
let lastsearch = @/
let @/ = '<<<<<<<'
execute "normal! ?\<cr>dd"


let @/ = '|||||||'
execute "normal! /\<cr>V"


let @/ = '======='
execute "normal! /\<cr>d"


let @/ = '>>>>>>>'
execute "normal! /\<cr>dd"


let @/ = lastsearch
endfunction


function! MergeKeepRight()
let lastsearch = @/
let @/ = '<<<<<<<'
execute "normal! ?\<cr>V"


let @/ = '======='
execute "normal! /\<cr>d"


let @/ = '>>>>>>>'
execute "normal! /\<cr>dd"


let @/ = lastsearch
endfunction