:Gdiff
命令与在该文件上运行git diff
相当。
git diff --staged
或git diff --cached
的等效命令是什么?
:Gdiff
命令与在该文件上运行git diff
相当。
git diff --staged
或git diff --cached
的等效命令是什么?
:Git
命令,你会看到一个窗口,里面的内容如下:# Head: master
# Merge: origin/master
# Help: g?
#
# Staged (1)
# M example.txt
#
向下滚动到暂存文件,example.txt
,然后按下 dd。这将打开一个差异视图,比较在HEAD和索引中的内容。您会注意到底部的栏上两个文件名都是特殊的Fugitive文件名。
此外,在 :Git
预览窗口中,您可以按下 g?,它将列出当前上下文中有效的所有映射。
dd
代替。" - jmmdd
删除一行。而 :Gstatus
后跟 dd
则会执行不同的操作。 - Konrad Rudolph:Gstatus
(现已弃用,改为使用 :Git
),在光标位于要查看差异的文件上方时键入 dd
。请参阅 :help fugitive-maps
以获取更多在 :Git
缓冲区中使用的按键绑定。 - Jonathan Barbervim-fugitive
没有提供直接对应git diff --staged
或git diff --cached
的功能,但它提供了一个通用的Vim命令:Git!
,可以将任意git
命令的输出导入只读Vim缓冲区。在此之前,我们需要明确重述问题:git diff --staged
和git diff --cached
是相同操作的同义词:对比索引(所有暂存更改的集合)与HEAD(当前分支的最新提交)的内容,通常用于在提交前审核更改。因此,所述问题变成了:“vim-fugitive
中审查所有已暂存更改的最有效方法是什么?”很明显,目前被接受的自我回答未能解决这个问题。排名第二的自我回答也不是更好的选择。
:Gstatus
绑定仅适用于当前行的文件,因此根据定义,无法用于查看所有已暂存的更改。此外,:Gstatus
D
绑定甚至不会为当前行的文件审查所有已暂存的更改。它只会对该文件的索引和工作树副本进行差异比较,而不是对该文件的索引和最近提交的副本进行差异比较(这是完全不同的情况)。
:Gdiff HEAD
同样不适用。它只会对与当前缓冲区对应的文件的最近提交和工作树副本进行差异比较。没有参数的 :Gdiff
等效于 :Gstatus
D
绑定,再次对该文件的索引和工作树副本进行差异比较。两者都不会审查所有已暂存的更改。
emaniacs 在对后一个答案的评论中接近了可行的解决方案:
:Git diff --staged
现在我们正在逼近真相!
:Git
将传递的 git
命令的输出管道传输到当前外部分页器,允许轻松查看所有在 Vim 外部暂存的更改。但是问题在于:在 Vim 外部。这意味着没有 Vim 绑定、缓冲区或语法高亮。理想情况下,我们希望一个只读的 Vim 缓冲区语法高亮显示 git diff --staged
的输出。我们能做到吗?
我们可以做到,否则 Tim Pope 不会成为 Vim 教皇。带有 !
后缀的 :Git
正是如此,允许在 Vim 中悠闲地查看所有暂存更改,并且带有基于 Vim 的语法高亮显示更改差异:
:Git! diff --staged
是的。它非常棒。
但是让我们再进一步。按照懒惰人的惯例,让我们定义一个新的Vim命令:Greview
来封装这个操作,并且定义一个新的绑定<leader>gr
来运行这个命令。只需要将以下代码添加到您的.vimrc
文件中:
command Greview :Git! diff --staged
nnoremap <leader>gr :Greview<cr>
<leader>
是,
,那么审查所有已暂存的更改就变成了,gr
。这再也不能更Vim了。:Greview
必须 是 vim-fugitive
的一部分! - jackyalcinecommand Greview :Gtabedit! diff --staged
。 - ssaid:Gdiff HEAD
Gdiff
需要一个修订参数。因此,您可以将HEAD
传递给它。这与git diff --staged
不等效,但它可以起到类似的作用。
:Git diff --staged
,因为 :Git
等同于 git
命令。 - emaniacs:Gdiff
那样使用Vim的差异功能打开差异。 - Flimm:Gtabedit @:% | Gdiff :
。:Gdiff
一样在分割视图中打开,而不是将diff语法转储到单个缓冲区中。完成后,只需使用:tabc
返回。Gtabedit
打开一个新的标签页并编辑fugitive对象:
@
(HEAD),指定文件:
,当前文件%
。Gdiff
将当前缓冲区与另一个fugitive对象进行比较:
:
(您可以再次使用:%
指定文件,但不需要)。git diff
(:Gdiff
)和git diff --staged
(上面的命令)的fugitive等效物。要在当前文件上获得git show
的行为,请使用:Gtabedit @~:% | Gdiff @
。:help fugitive-object
D
键时,当前版本的fugitive会自动执行此操作。如前所述,Gdiff
,Gdiff :
或Gdiff :0
将为您提供与索引的差异,
Gdiff -
或Gdiff HEAD
将为您提供与HEAD的差异。
因此,首先使用:
进行差异处理,然后再使用-
在vim中显示3个差异面板:
command! -bar Gvstage :Gvdiff -|Gvdiff : " vertical 3-split
command! -bar Gsstage :Gsdiff -|Gsdiff : " horizontal 3-split
Gvdiff -
。diffput
操作,反之亦然。由于HEAD上的modifiable
是关闭的,因此它永远不可能被定位。diffput
和diffget
命令添加一些快捷方式。请注意,它们可以接受“缓冲区指定符”,该指定符可以是一个模式(参见:help merge)或缓冲区编号。我修改了以前的命令,保存了初始缓冲区的编号,并对其他内容使用了模式。command! -bar Gvstage :let t:working_copy=bufnr('%')|Gvdiff -|Gvdiff : " vertical 3-split
command! -bar Gsstage :let t:working_copy=bufnr('%')|Gsdiff -|Gsdiff : " horizontal 3-split
nnoremap <Leader>hg :diffget fugitive://*/.git//[0-9a-f][0-9a-f]*/<CR> " HEAD get
nnoremap <Leader>ig :diffget fugitive://*/.git//0/<CR> " index get
nnoremap <Leader>ip :diffput fugitive://*/.git//0/<CR> " index put
nnoremap <Leader>wg :diffget <C-R>=t:working_copy<CR><CR> " work get
nnoremap <Leader>wp :diffput <C-R>=t:working_copy<CR><CR> " work put
或者,如果您只想要一个漂亮的vimdiff
视图来查看已暂存的内容而不是补丁,请让我建议:
command! Greview :exec "Git difftool --tool=vimdiff --staged " . fugitive#buffer().path()
这将启动一个新的vim实例,因此当您退出它时,您会回到您已经打开的标签和窗口,这是非常完美的。对我来说,这比通过git状态窗口进行过渡更快,但缺点是您无法编辑暂存的文件。
简述:
Gtabedit :0 | Gdiffsplit @:#
说明:
当您同时具有暂存更改和未暂存更改时,有3个相关的差异。以下分别使用 git
和 vim-fugitive
显示了每个差异。所有vim-fugitive
命令都在当前编辑器会话中打开实际的 vim diff。
NB: Gdiffsplit HEAD
的行为类似于 git diff HEAD -- <current_file>
,而不是 git diff --staged <current_file>
。
比较最后一次提交和暂存更改之间的差异,不包括未暂存的更改。即如果您现在运行 git commit
(不带 -a
),实际上会提交什么。这是原始问题的答案:
git diff --staged <current_file>
或 git diff --cached <current_file>
Gtabedit :0 | Gdiffsplit @:#
或 Gtabedit @:% | Gdiffsplit :0
(这里的 2 个 vim-fugitive
变体只是更改了窗口的顺序)
比较工作目录(未暂存)和暂存更改之间的差异。即如果您现在运行 git add <current_file>
,会将什么添加到索引中:
git diff <current_file>
Gdiffsplit
比较所有更改(已暂存和未暂存)与最后一次提交之间的差异。即如果您现在运行 git commit -a
,会提交什么:
git diff HEAD -- x
Gdiffsplit HEAD
git commit
命令将包括其他已跟踪的文件。
注意:为什么需要另一个答案?
git diff --staged
与git diff HEAD
混淆了(当您有暂存和未暂存的更改时,可以看到这一点)Gdiff
即Gdiffsplit
的实际行为)如果有人偶然发现了这个问题。
:Gdiff --staged
会起作用的.. :)