该命令:Gdiff
相当于git diff
在该文件上运行。
git diff --staged
or的等价物是git diff --cached
什么?
我找到了一种方法来做到这一点。运行:Gstatus
,你应该得到一个窗口,其内容如下:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: example.txt
#
向下滚动到暂存文件,example.txt
然后按Shift+ D。这将打开一个差异视图,比较 HEAD 中的内容和索引中的内容。您会在底部的栏上注意到这两个文件名都是特殊的逃犯文件名。
此外,在 Gstatus 预览窗口中,您可以按g?,这将列出在当前上下文中有效的所有映射。
虽然vim-fugitive
不提供or的直接类似物,但它提供了一个通用的 Vim 命令,用于将任意命令的输出通过管道传输到只读的 Vim 缓冲区:.git diff --staged
git diff --cached
git
:Git!
在我们开始之前,让我们明确地重申这个问题。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 Pope。-!
后缀的变体就是:Git
这样做的,它允许轻松地查看 Vim 中的所有阶段性更改,并使用基于 Vim 的语法突出显示更改差异:
:Git! diff --staged
是的。这真是太棒了。
但是,让我们更进一步。在到处都是懒惰的懒鬼的悠久传统中,让我们定义一个:Greview
封装这个操作的新 Vim 命令和一个<leader>gr
运行这个命令的新绑定。只需将以下内容存储到您的.vimrc
:
command Greview :Git! diff --staged
nnoremap <leader>gr :Greview<cr>
假设<leader>
是,
,审查所有阶段性更改减少到,gr
. 它无法得到任何Vimmier。
:Gdiff HEAD
Gdiff
接受修订参数。所以你可以通过它HEAD
。这不等同于git diff --staged
,但可以达到类似的目的。
更新:2017 年 3 月 28 日,
当您按下D
文件时,当前版本的逃犯会自动执行此操作。
如果文件是暂存的,则差异中只会显示暂存的更改。如果文件未暂存,则只有未暂存的更改可见。
如前所述,Gdiff
,Gdiff :
或Gdiff :0
为您提供带有索引的差异
,Gdiff -
或为您Gdiff HEAD
提供带有 HEAD 的差异。
因此,首先在 vim 中:
使用-
show 3 diff-panes 进行 diff:
command! -bar Gvstage :Gvdiff -|Gvdiff : " vertical 3-split
command! -bar Gsstage :Gsdiff -|Gsdiff : " horizontal 3-split
当然,Gvdiff -
如果您已经处于差异模式,您也可以这样做。
现在,通过 3 个打开的窗口推送和获取更改稍微复杂一些,但是,您可以diffput
轻松地从索引到工作树,反之亦然,因为 HEADmodifiable
已关闭,因此它永远不会成为目标。
否则,您可以为diffput
anddiffget
命令添加一些快捷方式,知道它们可以采用“缓冲区说明符”,可以是模式(请参阅 :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 @:% | Gdiff :
.
这比其他答案更好,因为它像 一样在拆分视图中打开:Gdiff
,而不是将 diff 语法转储到单个缓冲区中。当你完成后,只是:tabc
为了回来。
Gtabedit
打开一个新选项卡并编辑一个逃犯对象:
@
(HEAD),特定文件:
,当前文件%
。Gdiff
将当前缓冲区与另一个逃犯对象进行比较:
:
(您可以再次指定文件,:%
但不需要)。我们现在有git diff
( :Gdiff
) 和git diff --staged
(上面的命令) 的逃犯等价物。要获取git show
当前文件的行为,请使用:Gtabedit @~:% | Gdiff @
.
:help fugitive-object
如果你有人偶然发现了这个问题。
:Gdiff --staged
会做.. :)