【发布时间】:2013-03-02 16:57:13
【问题描述】:
命令:Gdiff 相当于在该文件上运行git diff。
git diff --staged 或 git diff --cached 的等价物是什么?
【问题讨论】:
标签: vim-fugitive
命令:Gdiff 相当于在该文件上运行git diff。
git diff --staged 或 git diff --cached 的等价物是什么?
【问题讨论】:
标签: vim-fugitive
我找到了一种方法来做到这一点。运行: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?,这将列出当前上下文中所有有效的映射。
【讨论】:
dd弃用
dd 在正常模式下删除一行。而:Gstatus 后跟dd 则有所不同。
虽然vim-fugitive 确实不提供git diff --staged 或git diff --cached 的直接类似物,但它确实提供了一个通用的 Vim 命令来管道输出任意git 命令进入只读 Vim 缓冲区::Git!。
在我们开始之前,让我们明确地重申这个问题。 git diff --staged 和 git diff --cached 是相同底层操作的同义词:将索引的内容(所有分阶段更改的集合)与 HEAD 的内容(当前分支的最新提交)进行比较,通常用于查看更改在提交之前。陈述的问题就变成了:
查看
vim-fugitive中所有阶段性更改的最有效方法是什么?
应该清楚的是,当前接受的自我回答无法解决这个问题。下一个评分最高的自我回答也好不到哪里去。
:Gstatus 绑定仅适用于当前行上的文件,因此根据定义不能用于查看所有分阶段的更改。此外,:GstatusD 绑定甚至不会检查当前行上文件的所有分阶段更改。它只比较该文件的索引和工作树副本,而不是比较该文件的索引和最近提交的副本(这是一个完全不同的野兽)。
:Gdiff HEAD 同样不适用。它只区分与当前缓冲区对应的文件的最近提交和工作树副本。没有参数的:Gdiff 等效于:Gstatus D 绑定,再次区分该文件的索引和工作树副本。两者均未审查所有阶段性更改。
emaniacs 对后一个答案的评论是最接近可行的解决方案:
:Git diff --staged
现在我们正在逼近真相!
:Git 将传递的git 命令的输出传送到当前的外部寻呼机,允许轻松地查看 Vim 外部的所有阶段性更改。但问题是:Vim 外部。这意味着没有 Vim 绑定、缓冲区或语法高亮。理想情况下,我们希望使用只读的 Vim 缓冲区语法突出显示 git diff --staged 的输出。我们可以这样做吗?
我们可以,否则 Tim Pope 不是 Vim 教皇。 !-suffixed 的 :Git 变体就是这样做的,它允许对所有分阶段的更改进行轻松的审查 在 Vim 完成,并带有基于 Vim 的语法突出显示更改差异:
:Git! diff --staged
是的。真是太棒了。
但让我们更进一步。在到处都是懒惰的懒鬼的悠久传统中,让我们定义一个新的 Vim 命令:Greview 封装这个操作和一个新的绑定<leader>gr 运行这个命令。只需将以下内容存储到您的.vimrc:
command Greview :Git! diff --staged
nnoremap <leader>gr :Greview<cr>
假设 <leader> 为 ,,审查所有分阶段的更改减少到 ,gr。它无法获得任何 Vimmier。
【讨论】:
:Greview需要成为vim-fugitive的一部分!
command Greview :Gtabedit! diff --staged
dd相同。
:Gdiff HEAD
Gdiff 接受修订参数。所以你可以通过HEAD。这不等同于git diff --staged,但可以起到类似的作用。
【讨论】:
:Git diff --staged,因为:Git等价于git命令。
:Gdiff 那样使用 Vim 的 diff 功能打开 diff。
更新:2017 年 3 月 28 日,
当您在文件上按D 时,当前版本的逃犯会自动执行此操作。
如果文件是暂存的,则只有暂存的更改会显示在 diff 中。 如果文件未暂存,则只有未暂存的更改可见。
【讨论】:
如前所述,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 -。
现在推送和获取更改在 3 个打开的窗口中稍微复杂一些,但是,您可以轻松地将 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 @:% | Gdiff :。
这比其他答案更好,因为它像:Gdiff 一样在拆分视图中打开,而不是将差异语法转储到单个缓冲区中。完成后,只需:tabc 即可返回。
Gtabedit 打开一个新标签并编辑一个逃犯对象:
@(HEAD),特定文件:,当前文件%。Gdiff 将当前缓冲区与另一个逃犯对象进行比较:
:(您可以使用:% 再次指定文件,但不是必需的)。我们现在有 git diff (:Gdiff) 和 git diff --staged(上面的命令)的逃犯等价物。要获取git show 在当前文件上的行为,请使用:Gtabedit @~:% | Gdiff @。
:help fugitive-object【讨论】:
如果你有人偶然发现了这个问题。
:Gdiff --staged
会的.. :)
【讨论】: