28

该命令:Gdiff相当于git diff在该文件上运行。

git diff --stagedor的等价物是git diff --cached什么?

4

7 回答 7

34

我找到了一种方法来做到这一点。运行: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?,这将列出在当前上下文中有效的所有映射。

于 2014-08-22T08:57:16.200 回答
21

虽然vim-fugitive不提供or的直接类似物,但提供了一个通用的 Vim 命令,用于将任意命令的输出通过管道传输到只读的 Vim 缓冲区:.git diff --stagedgit diff --cachedgit: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。

于 2015-04-05T05:35:25.457 回答
15
:Gdiff HEAD

Gdiff接受修订参数。所以你可以通过它HEAD。这不等同于git diff --staged,但可以达到类似的目的。

于 2013-07-18T10:22:34.020 回答
2

更新:2017 年 3 月 28 日,

当您按下D文件时,当前版本的逃犯会自动执行此操作。

如果文件是暂存的,则差异中只会显示暂存的更改。如果文件未暂存,则只有未暂存的更改可见。

于 2017-03-29T03:37:53.323 回答
2

如前所述,Gdiff,Gdiff :Gdiff :0为您提供带有索引的差异 ,Gdiff -或为您Gdiff HEAD提供带有 HEAD 的差异。

三分法

因此,首先在 vim 中:使用-show 3 diff-panes 进行 diff:

  1. 索引(“缓存”或“暂存”)
  2. 工作树
command! -bar Gvstage :Gvdiff -|Gvdiff : " vertical 3-split
command! -bar Gsstage :Gsdiff -|Gsdiff : " horizontal 3-split

当然,Gvdiff -如果您已经处于差异模式,您也可以这样做。

现在,通过 3 个打开的窗口推送和获取更改稍微复杂一些,但是,您可以diffput轻松地从索引到工作树,反之亦然,因为 HEADmodifiable已关闭,因此它永远不会成为目标。

否则,您可以为diffputanddiffget命令添加一些快捷方式,知道它们可以采用“缓冲区说明符”,可以是模式(请参阅 :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 状态窗口转换更快(至少对我而言),但缺点是您无法编辑暂存文件。

于 2017-11-10T19:16:28.087 回答
2

使用:Gtabedit @:% | Gdiff :.

这比其他答案更好,因为它像 一样在拆分视图中打开:Gdiff,而不是将 diff 语法转储到单个缓冲区中。当你完成后,只是:tabc为了回来。

解释

  1. Gtabedit打开一个新选项卡并编辑一个逃犯对象:
    • 从提交@(HEAD),特定文件:,当前文件%
  2. Gdiff将当前缓冲区与另一个逃犯对象进行比较:
    • 从索引中:(您可以再次指定文件,:%但不需要)。

奖金

我们现在有git diff( :Gdiff) 和git diff --staged(上面的命令) 的逃犯等价物。要获取git show当前文件的行为,请使用:Gtabedit @~:% | Gdiff @.

参考

于 2018-12-14T21:32:24.160 回答
-3

如果你有人偶然发现了这个问题。

:Gdiff --staged

会做.. :)

于 2013-07-18T09:58:10.397 回答