使用 vimdiff 合并更改
Merge changes using vimdiff
在我的例子中,我有两个文件 file1 和 file2。使用 vimdiff,我想按如下方式合并更改:
- 在第一个区别中,将 file1 中的行放在 file2 中的行上方。这意味着差异如file2中的
Listing 2
和List 2
应该是List 2
,然后是合并文件中的Listing 2
。
- 在另一个变化中反转大小写。
快照如下所示。
我们如何使用 vimdiff 实现这一点?
可以通过Ctrlww[=在两个windows之间来回切换21=]。您可以从一个 window 复制一个 Ctrlww,然后粘贴到另一个。当您解决分歧时,亮点会改变并消失。
看看这个video。
您可以在 windows 之间切换并复制和粘贴以解决差异,正如@David W. 在他的回答中建议的那样,但是 Vim 也有专门的 :diffput
和:diffget
命令来简化这个。使用这些(或相应的普通模式do
和dp
命令),您不必在windows之间切换,并且范围默认为当前更改。
如果你需要添加而不是覆盖其他缓冲区的差异(这在经典的双向差异中是一个相当不寻常的情况),你仍然必须yank 原始行并 put 它们在 :diffget
.
之后
一个地方完成后,可以使用]c
、[c
命令跳转到下一个不同点。
您可以使用以下基本命令进行合并:
do - 从其他 window 获取更改到当前 window .
dp - 将当前 window 的更改放入另一个 window.
]c - 跳转到下一个更改。
[c - 跳转到上一个更改。
zo - 打开折叠线。
zc - 关闭折叠线。
zr - 完全展开两个文件。
zm - 完全折叠两个文件。
Ctrlww - 改变window .
:only | wq
- 退出其他windows,写入并退出。
需要注意的怪癖
do和d p 如果您在正常模式下进行更改(或仅更改一行下的一行),但在可视模式下则不工作。
撤消命令仅在已更改的缓冲区中有效,因此如果您使用 dp 和改变主意,您需要切换到另一个缓冲区才能撤消。
:diffupdate
将重新扫描文件以进行更改(Vim 可能会混淆,并显示虚假内容)。
可视化模式和更细粒度的控制
在可视模式下 select 编辑文本行时,您必须使用普通命令:
:'<,'>diffget
和
:'<,'>diffput
.
例如:
- 进入可视模式并标记一些text/lines。
- 然后键入
:diffput
将 selected 行推送到另一个文件或 :diffget
从另一个文件中获取 selected 行。
要强调这一点:这意味着如果有一个由多行组成的更改块,那么 select 一个行的子集并发布 :diffput
将只应用这些更改其他缓冲区。
(:diffget
和 :diffput
也接受范围,有关更多信息,请参阅 :h copy-diffs
。)
比较内部的两个缓冲区 Vim
如果您分块加载两个文件(:vs
或 :sp
),您可以在每个 window 上执行 :diffthis
并实现文件差异已经加载到缓冲区中。
:diffoff
可用于关闭diff模式
This Vimcasts post and video 在实践中证明这一点。
如何在缓冲区之间应用所有更改
确保所有参与的缓冲区都处于 diff 模式(参见 :h start-vimdiff
)
一个。获取从缓冲区到当前缓冲区的更改:
:%diffget <buffer-number>
b.将当前缓冲区的所有更改放入另一个缓冲区:
:%diffput <buffer-number>
(:%
是 select 整个文件的范围;参见 :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
在我的例子中,我有两个文件 file1 和 file2。使用 vimdiff,我想按如下方式合并更改:
- 在第一个区别中,将 file1 中的行放在 file2 中的行上方。这意味着差异如file2中的
Listing 2
和List 2
应该是List 2
,然后是合并文件中的Listing 2
。 - 在另一个变化中反转大小写。
快照如下所示。
我们如何使用 vimdiff 实现这一点?
可以通过Ctrlww[=在两个windows之间来回切换21=]。您可以从一个 window 复制一个 Ctrlww,然后粘贴到另一个。当您解决分歧时,亮点会改变并消失。
看看这个video。
您可以在 windows 之间切换并复制和粘贴以解决差异,正如@David W. 在他的回答中建议的那样,但是 Vim 也有专门的 :diffput
和:diffget
命令来简化这个。使用这些(或相应的普通模式do
和dp
命令),您不必在windows之间切换,并且范围默认为当前更改。
如果你需要添加而不是覆盖其他缓冲区的差异(这在经典的双向差异中是一个相当不寻常的情况),你仍然必须yank 原始行并 put 它们在 :diffget
.
一个地方完成后,可以使用]c
、[c
命令跳转到下一个不同点。
您可以使用以下基本命令进行合并:
do - 从其他 window 获取更改到当前 window .
dp - 将当前 window 的更改放入另一个 window.
]c - 跳转到下一个更改。
[c - 跳转到上一个更改。
zo - 打开折叠线。
zc - 关闭折叠线。
zr - 完全展开两个文件。
zm - 完全折叠两个文件。
Ctrlww - 改变window .
:only | wq
- 退出其他windows,写入并退出。
需要注意的怪癖
do和d p 如果您在正常模式下进行更改(或仅更改一行下的一行),但在可视模式下则不工作。
撤消命令仅在已更改的缓冲区中有效,因此如果您使用 dp 和改变主意,您需要切换到另一个缓冲区才能撤消。
:diffupdate
将重新扫描文件以进行更改(Vim 可能会混淆,并显示虚假内容)。
可视化模式和更细粒度的控制
在可视模式下 select 编辑文本行时,您必须使用普通命令:
:'<,'>diffget
和:'<,'>diffput
.
例如:
- 进入可视模式并标记一些text/lines。
- 然后键入
:diffput
将 selected 行推送到另一个文件或:diffget
从另一个文件中获取 selected 行。
要强调这一点:这意味着如果有一个由多行组成的更改块,那么 select 一个行的子集并发布 :diffput
将只应用这些更改其他缓冲区。
(:diffget
和 :diffput
也接受范围,有关更多信息,请参阅 :h copy-diffs
。)
比较内部的两个缓冲区 Vim
如果您分块加载两个文件(:vs
或 :sp
),您可以在每个 window 上执行 :diffthis
并实现文件差异已经加载到缓冲区中。
:diffoff
可用于关闭diff模式
This Vimcasts post and video 在实践中证明这一点。
如何在缓冲区之间应用所有更改
确保所有参与的缓冲区都处于 diff 模式(参见
:h start-vimdiff
)一个。获取从缓冲区到当前缓冲区的更改:
:%diffget <buffer-number>
b.将当前缓冲区的所有更改放入另一个缓冲区:
:%diffput <buffer-number>
(:%
是 select 整个文件的范围;参见 :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