Есть ли способ подключить сохранение в Vim к коммиту в git?

11

Я новичок в мире Vim и хочу сделать так, чтобы каждый раз, когда я сохранял файл, он передавался на контроль версий. Это возможно?

gonzo.floyd
источник

Ответы:

4

Вы можете использовать автокоманды Vim:

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

Это не проверено, но он должен добавить файл и зафиксировать его с именем файла как сообщение о коммите.
Вы хотите BufWritePost, так как это срабатывает после записи файла. Я думаю, что есть много утомительных или небезопасных крайних случаев.

donothingsuccessfully
источник
4

Я использую автокоманду vim, которую я помещаю в свой .vimrc. Команда сначала выполняет грубую проверку того, что мы работаем в каталоге 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
Отсутствует одинарная кавычка в конце cmd, сразу после fi.
Эндрю-Дюфрен
2
Эта версия работает, только если вы находитесь в корневом каталоге вашего репо. Лучшее решение - autocmd BufWritePost * execute '! if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1 ; then git add % ; git commit -m %; fi'из SO ответа
Эндрю-Дюфрен
Это работает для меня на Linux. Есть идеи, как заставить его работать на Windows?
user334287
2

Возможно, вы захотите заглянуть в беглый плагин, это очень мощный плагин для git для vim. Вы также можете настроить autocmdкак donothingsuccessfullyпредложено, но у него есть всплывающее окно :Gcommitили :Gstatus(из которого вы можете выбрать изменения для добавления в индекс git)

mkomitee
источник
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. Фиксация должна быть значимой, а не сохранять в обычное время.

Обычно вы делаете коммит, потому что вы добавили функцию, исправили ошибку, а не только потому, что вы работали с файлом. У вас не будет некомпилируемого проекта или незавершенной функции.

M'vy
источник
Это правда, но я также хочу иметь скрипт на ночь, который перемещает файлы, которые успешно компилируются, из репозитория "save-on-commit" в репо "значимые изменения".
gonzo.floyd
Ну, это не совсем плохая идея с Git. «Часто совершайте» - это своего рода девиз. Это также работает лучше, потому что вы можете одновременно работать над одним файлом с несколькими разработчиками и минимальными проблемами. Было бы весьма полезно использовать механизм сохранения в vim.
Метаграф
Рабочие процессы в Git могут радикально отличаться от Subversion. Вы, возможно, никогда не сделаете этого в svn, потому что это было бы оскорбительно, но оно имеет вполне допустимое применение в git. Например, какой-нибудь тестовый сервер интеграции может быть подключен к тестовой ветке. Автоматическая фиксация при сохранении становится весьма полезной. Когда вы дойдете до того, что что-то работает, вы будете использовать git rebase, чтобы объединить все действия в один коммит с осмысленным сообщением, а затем слиться с вашей веткой devel. Если это звучит страшно или сложно, то только потому, что вы адаптированы к ограничениям нераспределенного исходного кода vcs.
Калеб
0

Я знаю, что этот вопрос старый и это явное самореклама, но я написал плагин Vim, который будет запускать определенные сценарии оболочки после определенных autocmdсобытий Vim . Например, названный скрипт .bufwritepost.vimhook.shбудет запускаться (синхронно) каждый раз при запуске BufWritePostкоманды. После этого вы можете легко включить любую логику для выполнения коммита git внутри этого скрипта. Плагин принимает определенные соглашения об именах этих сценариев, а также поддерживает сценарии «ловушки», которые запускаются только для файлов, соответствующих определенным именам или имеющих определенные расширения.

Полная информация: https://github.com/ahw/vim-hooks

Эндрю
источник
0

Я хочу сообщить о своем взгляде на эту проблему.

У меня есть vimrc.vimв репозитории git ( $VIMCONFс начальной загрузкой .vimrc) и отображается <Leader>ve("vim edit"), чтобы открыть vimrc в новой вкладке. Это не влияет на текущий рабочий каталог.

Так что, если я редактирую vimrc.vimиз vim, запущенного в другом каталоге за пределами моего хранилища vim git, подход, который обсуждал Ник Эдвардс, потерпит неудачу. Мой взлом заключается в следующем (для 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. Для окон я меняю каталог на местоположение файла vimrc. Это не самое лучшее, и я могу изменить позже, чтобы быть похожим на Linux. Не принимайте это слишком серьезно, но вы можете использовать его в качестве руководства. gitдолжен находиться в пути (вы должны быть в состоянии напечатать git <ENTER>в cmd.exe)
  2. Для Linux я сначала проверяю, что я редактирую права vimrc.vim
  3. Сохранить текущий рабочий каталог в tempdir
  4. Перейдите в файл vimrc.vim
  5. Сделать мерзавец совершить
  6. Вернуться в предыдущий рабочий каталог
  7. Я вручную нажимаю изменения мерзавца

Ноты:

  1. Команды могут быть «связаны» в vim с |. Цепочка будет прервана, если какая-либо из команд не будет выполнена. Чтобы разбить несколько строк, начните следующую строку с \.
  2. Это может быть расширено до файлов ftplugin. Ваши фильтры будут *.vimиexpand($VIMCONF)."/ftplugin/"
user334287
источник