Vim 与 Git 如何交互 已翻译 100%

ismdeep 投递于 2018/12/06 11:40 (共 13 段, 翻译完成于 12-24)
阅读 3690
收藏 26
4
加载中

Vim和Git都是高度复杂,可配置的开发者工具。使用Vim工具的开发者可能也需要频繁使用Git工具。这篇文章尝试探索这两个工具如何在多种方式下进行交互。

开始时,我不打算约束任何特定的工作流,或者争论、反对一个特定的方法。仅仅是有太多的选择,同时鼓励你开发你自己的工作流。

Vim和Git是两个独立的工具,当然可以以各自独立的方式使用。然而,如果将两个工具整合会很有用,能够节约时间,和带来便利。

注意:就个人而言,我使用Neovim,但是实际上这和Vim工具中每一个功能都是相同的。假定本文中的“Vim”指的是Neovim和Vim,除非有明确的区别。

硅谷课堂
硅谷课堂
翻译于 2018/12/13 10:02
0

Git 角度

从Git角度来说,有如下几种机会使用Vim工具:

  • 编辑评论/标签信息,

  • 解决合并冲突(哇!)

  • 交互式重建

编辑评论信息

如果你已经将编辑器的环境变量设置成了Vim,Git会自动使用Vim来编辑信息。如果不依赖环境变量,core.editor的git 配置可以按如下方式设置:

[core]
    editor = "vim"

当在Vim工具中编辑一条评论信息时,你想要终止,则可以使用:cq命令以non-zero状态退出。这样操作后Git会取消评论信息,及时你已经开始写了一套信息。同样,这个命令能够用于终止一个合并或者退出 difftool操作,如果相应的trustExitCode 选项设置的值是true:

[difftool]
    trustExitCode = true

# the option is mergetool.<tool>.trustExitCode
# replace nvimdiff4 with the name of the mergetool you use
[mergetool "nvimdiff4"]
    trustExitCode = true
    ...

此外,确定使用 git commit -v命令 或者在你的git配置文件中设置 commit.verbose = true 这样当你编辑评论信息时才会在Vim中显示所有的补丁信息。

硅谷课堂
硅谷课堂
翻译于 2018/12/13 10:26
0

解决合并重复

在尝试通过外部工具解决重组之前,可以考虑借助Vim自身出色的差异模式(译者注: diffmode,下同)。可以将Vim配置为使用Git的mergetool,当运行git mergetool命令时,它就会自动启动来协助完成代码的合并操作。我使用的两个主要的方法是:以diff模式启动的vanilla Vim(或者Neovim),以及vim-fugitive提供的Gdiff命令。下面是示例配置(这是我的Neovim配置,和以diff模式启动的vim有少许不同)

[merge]
    tool = nvimdiff4
    # if not using a tool name with builtin support, must supply mergetool cmd
    # as below

[mergetool "nvimdiff4"]
    cmd = nvim -d $LOCAL $BASE $REMOTE $MERGED -c '$wincmd w' -c 'wincmd J'

[mergetool "nfugitive"]
    cmd = nvim -f -c "Gdiff" "$MERGED"

第一种方法不需要安装任何插件。它只是以差异模式启动Vim(Neovim)显示Git在环境变量中设置的四个文件。窗口命令可以将工作文件移动到一个全宽半高的窗口中。

第二种方法使用vim-fugitive插件自动设置布局(它会根据终端的尺寸选择水平还是垂直的窗口排列方式。它仍旧使用Vim的差异模式,不过只显示三个文件:本地、远程和索引)

这两种方法都使用diffget和diffput命令(相应地do和dp)来解决冲突。有帮助的一点是,可以在状态行中包含缓冲数字,那么就可以在使用do和dp命令需要指定缓存数字时做个快速的参考。参数%n可以实现这个功能,更详细的信息可以通过:h 'statusline'查看。

更进一步的内容,我建议参考:《Vimcasts screencast on resolving merge conflicts

同样,git difftool也可以设置使用Vim来展示版本差异:

[diff]
    tool = nvimdiff2

[difftool "nvimdiff2"]
    cmd = nvim -d $LOCAL $REMOTE

 

kjmeng
kjmeng
翻译于 2018/12/19 11:31
0

交互式Rebase

由于我在rebase上没有太多的经验,因此在这个主题上我没有权威的观点。但是为了完整性,还是把这个主题放在这里了。

我也的确知道Vim可以完美地完成这个任务。操作和 Vim 命令的对应如下:

任务Vim命令
更改一个提交(译者注:原文是command,但是应该是commit)ciw
移除一个提交dd
记录行<count> dd, 向上/向下,p或者P

Vim同样包含了一些命令来快速改变一个提交(:Pick,:Squash)或者它们之间的cycle(:Cycle)。可以在gitrebase.vim上找到所有的可用命令。也可增加按键绑定来提高效率。

kjmeng
kjmeng
翻译于 2018/12/19 13:50
0

Vim视角

那么换个角度看问题:怎么把Git集成到Vim中呢?

Vanilla

首先咱们从不需要插件的事情开始。

:!git

一种方式就是直接将命令通过shell送给Git。需要注意的是,在这种模式下Neovim交互式标准输入是不起作用的,所以prompt类型的输入都是无效的。

:!git stash

:terminal

Neovim以及新版本的Vim中都内嵌了终端,可以通过:terminal启动。启动的终端支持完整的Vim命令(以及完整的Git命令)。这种方法在使用Gvim或者不想挂起/退出Vim回到shell窗口时,十分有用。

kjmeng
kjmeng
翻译于 2018/12/19 11:50
0

配置

autoread选项可以让Vim在检测到文件被在外部修改时,可以自动再次加载文件。:checktime命令用来检查是否有缓存被其他程序修改。尤其是在autocmd中运行:checktime以防文件被外部修改的情况十分有用(我使用FocusGained和CursorHold)。当签出到不同提交上时,又不想被Vim提示由于文件被修改是否进行下一步操作时,它们一起使用就非常方便了。

set autoread
autocmd FocusGained,CursorHold ?* if getcmdwintype() == '' | checktime | endif

警告:这样配置后,一旦从磁盘加载了外部修改后,在Vim中所做的改动就会丢失。可以将Vim设置成自动写入,这样会更加保险一点。关于这个话题可以阅读这篇博文

没有人想提交合并冲突的标记,那么可以把它们高亮出来以免错过了:

match ErrorMsg '^\(<\|=\|>\)\{7\}\([^=].\+\)\?$'

通常来说,提交消息的首行应该是50个字符的最大宽度,而正文是72个字符的最大宽度。拼写的自动纠正也不错。简单配置一下,Vim都可以搞定:

" Note: put this in ftplugin/gitcommit.vim or in a filetype autocmd.

" show the body width boundary
setlocal colorcolumn=73
setlocal textwidth=72

" warning if first line too long
match ErrorMsg /\%1l.\%>51v/

" spell check on
setlocal spell
kjmeng
kjmeng
翻译于 2018/12/19 14:03
0

插件

Fugitive.vim

Git 插件。已有许多关于Fugitive的文章,所以我不会详细介绍之。基本上,它提供了许多用于处理repo 的 Vim 命令,用于暂存改动的 diff 设置,交互式状态窗口等。它功能非常强大,并且其文档和其他资源是非常值得阅读的,以便更多地了解使用 Fugitive 可以实现的目标。我强烈推荐关于Fugitive的Vimcasts系列文章

我持续实用的一些功能是:

  • %{FugitiveStatusline()} 用于在状态行显示当前分支。

  • :Gblame 用于在vim中立即执行git blame。

  • :Gdiff  用于暂存hunks以及查看diff。

Tocy
Tocy
翻译于 2018/12/18 18:36
0

GitGutter/Signify

GitGutter 和 Signify 都是以实现在符号列显示 diff 信息的插件。GitGutter 是为 Git 量身定制的,并提供了一些有用的附加功能,例如撤消hunk。Signify长期以来一直比较快,但近期在GitGutter上的重构工作已经拉平了竞争环境。如果你仅使用Git我会因为其附加功能而推荐GitGutter;如果你还需要支持其他VCS,我建议使用Signify。

两个插件都支持在状态行中嵌入已添加/已删除/已修改行数的功能。例如,我当前的状态行生成函数包括:

let l:hunks = GitGutterGetHunkSummary()
if l:hunks[0] || l:hunks[1] || l:hunks[2]
  let l:line .= '%#GitGutterAdd# +' . l:hunks[0] .
              \ ' %#GitGutterChange#~' . l:hunks[1] .
              \ ' %#GitGutterDelete#-' . l:hunks[2] . ' '

 

GV

GV 是Vim之上的极好的Git浏览器。

Tocy
Tocy
翻译于 2018/12/18 18:44
0

Vimagit

Vimagit 是将一些Emacs着名的 Magit 带入 Vim 中的一次尝试。它提供了一个缓冲区,你可以在其中启动 Git 命令,暂存 hunk/文件和提交。它的界面非常不错(恕我直言),但遗憾的是它的性能很糟糕。它是值得一试的,但可能还不够成熟,无法支持高效的工作流程。

Committia

Committia 是一个简单的插件,通过在垂直分割中显示差异以使得编辑待提交消息更加顺畅。我发现它非常有用,直到我发现 git commit 的详细模式,它将 diff 也加载到缓冲区中。我认为它仍颇具潜力,因为它提供了整洁的布局和对 diff 缓冲浏览的绑定信息。

Tocy
Tocy
翻译于 2018/12/18 18:50
0

分支管理器

我最近发现了一些好用的管理Git分支的插件(以及相关工作)。TwiggyMerginal 插件功能很像,这两个插件都有一个打开buffer的命令,这个命令用在执行垂直分隔的操作上,如转换,合并,拉取,提交,存贮和删除等操作。这些是最近发现的一些插件同时我相信还会有更多好的插件推出。我同时认为这些功能突出了Vim插件生态系统的丰富性。有这么多不被人所知道的但很有用的插件,这些插件会完美的适用于你的工作流中。

硅谷课堂
硅谷课堂
翻译于 2018/12/14 10:52
0
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(4)

老大哥
老大哥
vscode解千愁
帖子列表
帖子列表
真折腾
xiaoshiyue
xiaoshiyue
我没有抓狂
我没有抓狂
It's Magit
返回顶部
顶部