有什么方法可以将保存在Vim中挂钩到在git中提交吗?


11

我是Vim的新手,我想做到这一点,以便每次保存文件时都将其提交给版本控制。这可能吗?

Answers:


4

您可以使用Vim的自动命令:

:autocmd BufWritePost * execute '!git add % && git commit -m %'

这未经测试,但是它应该添加文件并使用文件名作为提交消息来提交。
您需要BufWritePost,因为这是在写入文件后触发的。我想虽然有很多讨厌的或不安全的边缘情况。


4

我使用放置在.vimrc中的vim自动命令。该命令首先粗略检查我们是否在git目录中工作(通过检查.git目录(在当前目录中还是使用git rev-parse)的存在,然后使用,git -a -m %以便仅暂存和提交先前已添加的文件。

autocmd BufWritePost * execute '! if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1 ; then git add % ; git commit -m %; fi'

1
在fi之后,cmd的末尾缺少单引号。
Andrew-Dufresne 2012年

2
仅当您位于存储库的根目录中时,此版本才有效。更好的解决方案是autocmd BufWritePost * execute '! if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1 ; then git add % ; git commit -m %; fi'SO答案中获取答案
Andrew-Dufresne 2012年

这在Linux上对我有效。任何想法如何使其在Windows上工作?
user334287'2

2

您可能需要研究逃犯插件,它是vim的功能非常强大的git插件。您也可以autocmddonothingsuccessfully建议设置一个,但要弹出它:Gcommit:Gstatus(您可以从中选择要添加到git索引的更改)


1

以其他人提供的答案为基础:

autocmd BufWritePost * execute ':silent ! if git rev-parse --git-dir > /dev/null 2>&1 ; then git add % ; git commit -m "Auto-commit: saved %"; fi > /dev/null 2>&1'

这是完全透明的。您不会收到“按Enter继续”消息(但是,如果提交不起作用,您将不会知道它失败了)。


0

您肯定可以在宏或命令重新映射的情况下这样做。

(检查/programming/117150/can-i-re-map-commands-in-vim

我不确定这是否是一个好选择。我暂时不精通git,我知道它有时与svn不同。但是我不会使用svn进行自动提交。提交需要有意义,而不是定期保存。

通常,提交是因为您添加了一个功能,解决了一个错误,而不仅仅是因为您在处理文件。您将不会遇到未编译的项目或未完成的功能。


没错,但是我还想拥有一个通宵脚本,将成功编译的文件从“提交时保存”存储库移动到“有意义的更改”存储库。
gonzo.floyd 2011年

好吧,对于Git来说,这并不是一个坏主意。“经常提交”是一种座右铭。它也可以通过这种方式更好地工作,因为您可以与多个开发人员并发处理最少的问题,并发处理同一个文件。插入vim的save机制将非常有用。
Metagrapher 2011年

Git中的工作流程可能与Subversion完全不同。您可能永远不会在svn中执行此操作,因为它会被滥用,但是它在git中具有完全有效的用法。例如,某种类型的测试集成服务器可以连接到测试分支。保存时自动提交就变得非常有用。当您确定某件事正在起作用时,您将使用git rebase将所有活动压缩为具有有意义消息的单个提交,然后合并到您的devel分支中。如果这听起来令人恐惧或复杂,那仅仅是因为您适应了非分布式源vc的限制。
Caleb 2014年

0

我知道这个问题很老,这是公然的自我宣传,但是我写了一个Vim插件,它将触发特定的Shell脚本在特定的Vim autocmd事件之后运行。例如,.bufwritepost.vimhook.sh每次启动BufWritePost命令时,都会(同步)运行名为的脚本。然后,您可以轻松地在该脚本中包含执行git commit所需的任何逻辑。该插件假定这些脚本具有特定的命名约定,并且还支持“挂钩”脚本,该脚本仅在与某些名称匹配或具有某些扩展名的文件上触发。

完整详细信息:https : //github.com/ahw/vim-hooks


0

我想报告我对这个问题的看法。

vimrc.vim在git信息库($VIMCONF具有bootstrap .vimrc)中进行了映射,并进行了映射<Leader>ve(“ vim edit”)以在新标签页中打开vimrc。这不会影响当前的工作目录。

因此,如果我vimrc.vim从vim git存储库之外的其他目录中开始的vim 编辑,则Nick Edwards讨论的方法将失败。我的技巧如下(适用于Windows和Linux)

if has('win32')
    " The git command has to be passed to git. So we need to call bash.exe.
    autocmd BufEnter *vimrc.vim silent! lcd %:p:h
    autocmd BufWritePost *vimrc.vim if expand('<amatch>') =~ substitute(expand('$VIMCONF\vimrc.vim'), '\', '/', "g") | execute '! git add % & git commit -m %' | endif
else " Linux
    autocmd BufWritePost *vimrc.vim
        \ if expand('<amatch>') =~ expand($VIMCONF)."/vimrc.vim" |
        \ let tempdir = getcwd() | execute 'cd' fnameescape(expand('<amatch>:h')) | 
        \ execute '! if git rev-parse --git-dir > /dev/null 2>&1 ; then git add % ; git commit -m % ; fi' |
        \ execute 'cd' fnameescape(tempdir) |
        \ endif
endif

说明:

  1. 对于Windows,我将目录更改为vimrc文件位置。这不是最好的,以后我可能会更改为类似于linux。不要太在意这个,但您可能希望将其用作指导。git已经是在路径(即你应该能够输入git <ENTER>cmd.exe
  2. 对于Linux,我首先检查是否编辑了正确的vimrc.vim。
  3. 将当前工作目录保存到 tempdir
  4. 将目录更改为vimrc.vim文件
  5. 做git commit
  6. 返回上一个工作目录
  7. 我手动推送git更改

笔记:

  1. 可以在vim中使用“链接”命令|。如果任何命令失败,链将中止。要突破多行,请从开始下一行\
  2. 可以扩展到ftplugin文件。您的过滤器将是*.vimexpand($VIMCONF)."/ftplugin/"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.