Vim по полной: Работа с Git


  1. Введение (vim_lib)
  2. Менеджер плагинов без фатальных недостатков (vim_lib, vim_plugmanager)
  3. Уровень проекта и файловая система (vim_prj, nerdtree)
  4. Snippets и шаблоны файлов (UltiSnips, vim_template)
  5. Компиляция и выполнение чего угодно (vim-quickrun)
  6. Работа с Git (vim_git)
  7. Деплой (vim_deploy)
  8. Тестирование с помощью xUnit (vim_unittest)
  9. Библиотека, на которой все держится (vim_lib)
  10. Другие полезные плагины


Часто ли вам приходится использовать Git? В смысле, вы коммитите изменения каждый час или каждые несколько минут? Я делаю это очень часто и не слежу за чистотой репозитория, так как считаю его не более чем журналом изменений, а не произведением искусства. Такой подход требует от редактора хорошей интеграцией с Git, позволяющей в пару нажатий клавиш создать новый коммит, вернуться в прежнее состояние, перейти на другую ветку и так далее. Если вы используете современную среду разработки, в которой реализована интеграция с Git, вам очень повезло, но что делать пользователям редактора Vim? Есть ли плагин, который не просто реализует Vim-команды по тиму GitCommit, GitCheckout и GitBranch, а предоставляет удобный интерфейс в лучших традициях редактора?
Когда я впервые задумался об интеграции Vim с Git, я, конечно же, попробовал готовые плагины и решения, но почему они все лишь реализуют команды редактора, а не предоставляют чего то большего? Я активно пользуюсь Git как с помощью CLI, так и посредством различных программ с GUI. У того и у другого есть свои плюсы и минусы, но в работе часто решаются следующие задачи:

  • Индексация и добавление коммитов
  • Просмотр изменений
  • Переход между ветками и слияние
  • Просмотр истории, ее фильтрация и переход в прежние состояния


У Git есть еще много полезного, но, как показала моя практика, чаще всего используются эти четыре действия. Важно отметить, что все они отнюдь не тривиальны. На пример, для добавления нескольких файлов в коммит нужно выполнить две команды и перечислить адреса этих файлов, что довольно долго (при использовании CLI). С другой стороны, постоянно переключаться между редактором и используемой программой с GUI для работы с Git тоже довольно накладно, так как, лично мне, тяжело переключаться между контекстом (читать — интерфейсом) используемого редактора (Vim) и GUI (мышь). Заметив это, я решил написать собственный плагин для Vim, который будет удобен пользователям этого редактора и при этом достаточно прост, даже для любителей GUI. Кстати, именно с этого плагина началась библиотека vim_lib, о которой вы уже слышали в прошлых моих статьях.

В чем же изюм этого плагина? С помощью горячих клавиш можно легко индексировать файлы, коммитить индекс и т.д. В свою очередь окна редактора используются плагином так, что получается GUI с привычным для пользователя Vim управлением. На пример, чтобы удалить ветку, достаточно открыть окно веток, навести курсор на нужную ветку и использовать dd, «как дома»!


Плагин, о котором я хочу рассказать называется vim_git. Плагин довольно сложный, так как я постарался учесть все потребности пользователя Git, от чего в нем реализовано множество возможностей, но в этой статье я постараюсь максимально просто и понятно об этом всем рассказать.

Об окнах


Для начала запомните: плагин активно использует окна (window) редактора как элементы графического интерфейса.

Пример
eee52622998446bdadf4d6397cec1a9b.png


Окна реализованы так, что используются они с помощью стандартных команд редактора Vim. То есть для выбора некоторого элемента, на пример ветки, нужно навести указатель (текстовый) на имя этой ветки, чтобы удалить ее используется команда dd, а для добавления команда a, и так везде. Все окна сопровождаются встроенной документацией, о которой сообщает подсказка вида «Branch list (Press? for help)». Нажав ?, подсказка будет развернута в том же окне.

Пример
2db93d137d4c4df19155833167e262fc.png


Достаточно просто?

Об API плагина


Так же вам стоит знать: все создаваемые мной плагины реализуют API в виде Vim функций. Так, все API данного плагина присутствует в виде функций vim_git#…, на пример vim_git#status, vim_git#tagList, vim_git#branchList и т.д. Большинство плагинов при этом реализуют как пункты меню Vim, которые используют API плагина, так и команды. Лично мне удобнее биндить клавиши, это быстрее любых меню и команд редактора, но я не настаиваю.

Вот пример того, как я забиндил клавиш для плагина vim_git:

Plugin 'vim_git', {
      \  'map': {
      \    'status':      'gs', " Окно статуса
      \    'log':         'gl', " Окно истории коммитов
      \    'branchList':  'gb', " Окно веток
      \    'tagList':     'gt', " Окно тегов
      \    'addCurrent':  'ga', " Добавить текущий файл в индекс
      \    'addAll':      'gA', " Добавить все изменения в индекс
      \    'commit':      'gc', " Коммит индекса
      \    'commitAll':   'gC', " Добавить все изменения в индекс и их коммит
      \    'pushCurrent': 'go', " Push
      \    'pullCurrent': 'gi', " Pull
      \    'remoteList':  'gr', " Окно удаленных репозиториев
      \  }
      \}


О стеке окон


Многие окна vim_git (как и всех моих плагинов) реализованы в виде стека. Это означает, что если в окне вы выполняете команду, которая приводит к открытию другого окна (на пример пытаетесь посмотреть различия между двумя коммитами), это новое окно будет открыто в текущем окне. Если вы закроете новое окно (на пример с помощью : q), то откроется первое окно. Таким образом вы используете стек окон.
Если эти моменты вам понятны, то переходим к делу.

Индекс


Для просмотра состояния индекса Git используется vim_git#status (или сочетание gs). Это окно содержит подробную информацию о состоянии репозитория и индекса в виде ответа самого Git. То есть никакой обработки плагин не выполняет, все стандартно.

Окно статуса
fb12cf83b7ad44a3ab41f9253050eae4.png


В данном окне реализованы следующие команды (сочетания клавишь):

  • a — добавить файл под курсором в индекс. При этом окно будет автоматически перерисовано и вы увидите что файл действительно добавлен в индекс. Чтобы не повторяться, все окна плагина перерисовываются автоматически по мере надобности
  • dd — удалить файл под курсором из индекса
  • da — удалить все файлы из индекса
  • u — восстановить файл под курсором в состояние последнего коммита
  • U — восстановить все файлы в состояние последнего коммита
  • d — показать изменения в файле в режиме
    Git-diff
    d786042ab53f4a75a622a1d30ec18441.png
  • D — показать изменения в файле в режиме
    Vim-diff
    8e9610ea2823450abee07369a2422afc.png


Коммит


При коммите плагин откроет новое окно, в котором вам будет необходимо написать комментарий. После сохранения и закрытия этого окна (на пример с помощью ZZ), коммит будет создан. Чтобы отменить создание коммита, достаточно закрыть окно без сохранения (: q! ). Естественно в коммит попадут только те изменения, которые были добавлены в индекс на момент выполнения коммита.

Окно коммита
808ecad5766847ff8aa03c69e1360e25.png


История коммитов


Для просмотра истории коммитов используется vim_git#log (или сочетание gl). Это окно выводит историю коммитов в двух режимах:

  • Классический — коммиты перечислены в виде блоков
    Пример
    1a546697ddae4109bb8f1dce6b5e1808.png

  • Граф — коммиты представлены в виде дерева
    Пример
    9bc61e311e8c4bd5a995e79f91a37a91.png


В данном окне реализованы следующие команды (сочетания клавиш):

  • Enter — перейти на указанный коммит
  • u — отменить изменения
  • d — показать разницу между текущим состоянием репозитория и указанным коммитом в режиме Git-diff
  • v — переключиться между режимами вывода истории (классический и граф)


Отдельно следует упомянуть о фильтре и состоянии коммита.

Фильтр истории


Команда (сочетание клавиш) f открывает диалог, в котором вы можете добавить различные фильтры для истории, будь то имя интересующего вас автора или дата создания коммита.

Диалог фильтра
b6d35050b9e6469f9d0e1cee55fab4fb.png


Состояние коммита


Если навести указатель на хэш интересующего нас коммита и нажать s, то откроется окно состояния коммита, в котором будут перечислены все измененные данным коммитом файлы.

Окно состояния коммита
99acc601fc16480fbdef2793951ea081.png


В этом окне реализованы следующие команды (сочетания клавишь):

  • d — изменения (в режиме Git-diff) в файле под курсором, внесенные коммитом
  • D — изменения (в режиме Git-vim) в файле под курсором, внесенные коммитом


Ветки


Для просмотра доступных веток (локальных и удаленных) используется vim_git#branchList (или сочетание gb).

Окно веток
7b1851ff41c84a23a48fa1adb7485cca.png


В данном окне реализованы следующие команды (сочетания клавишь):

  • Enter — перейти на ветку под курсором
  • a — добавить новую ветку
  • r — переименовать ветку под курсором
  • dd — удалить ветку
  • m — слить текущую ветку с веткой под курсором
  • o — push ветки (только для локальных веток)
  • d — показать разницу между текущей веткой и веткой под курсором (в режиме Git-diff)
  • s — показать состояне ветки (аналогично состоянию коммита)
  • i — слить изменения из удаленной ветки в текущую


Удаленные репозитории


Для просмотра зарегистрированных удаленных репозиториев используется vim_git#remoteList (или сочетание gr).

Окно удаленных репозиториев
30cde6f9101b4848a6ed629c9229fe02.png


В данном окне реализованы следующие команды (сочетания клавиш):

  • a — добавить новый псевдоним удаленного репозитория
  • dd — удалить псевдоним под курсором
  • r — переименовать псевдоним под курсором
  • f — получить изменения из репозитория под курсором
  • i — получить и слить изменения из удаленного репозитория под курсором в текущую ветку
  • o — отправить все изменения текущей ветки в удаленный репозиторий под курсором


Теги


Для просмотра тегов используется vim_git#tagList (или сочетание gt).

Окно тегов
8b86bd5369aa4879a97727757019ee36.png


В данном окне реализованы следующие команды (сочетания клавиш):

  • Enter — перейти на коммит, на который указывает тег под курсором
  • a — добавить новый тег для текущего коммита
  • A — добавить аннотирующий тег для текущего коммита
  • dd — удалить тег под курсором
  • s — показать информацию о теге


Сила плагина в удобном API и GUI, что позволяет мне активно пользоваться Git не выходя из редактора. Конечно я не осветил все функции vim_git, так как статья уже довольно длинна и не хочется утомлять читателя, потому вы найдете еще много интересного в этом плагине (на пример с помощью go легко push’ить, а с помощью gi pull’ить изменения).

© Habrahabr.ru