Можно ли запустить vimdiff для git diffs на вкладке текущего процесса?

Jan 20 2021

Скажем, у меня открыт файловый буфер и :terminalразделен на одну вкладку. Я хотел бы создать новую вкладку, на которой я бегу, vimdiffно показывает мой git diff. Я пытаюсь появиться git difftool HEAD~1в моем текущем процессе vim, просто на другой странице вкладки.

Возможно ли это на Vim 8 без плагинов?

У меня возникает иллюзия, когда я это делаю, :tab terminalа потом убегаю git difftool HEAD~1. Однако это запускает подпроцесс vim, и я бы хотел этого избежать.

Что-то вроде этого вопроса: как мне войти в режим vimdiff, если два разделения уже открыты? но для git diffs.

Ответы

2 NikolasTapia Jan 20 2021 at 17:03

Хотя это, безусловно, можно сделать в ванили vim, я предлагаю вам взглянуть на отличный vim-fugitiveплагин tpope . Тогда вам просто нужно сделать, :tab Gdiffчтобы получить то, что вы хотите.

Если вы действительно не хотите устанавливать какие-либо плагины, следующее может работать, если текущий файл находится в буфере №. 1:

  1. :tabnew | r! git show HEAD^:$(git rev-parse --show-prefix)#1:t
  2. Во вновь открытой вкладке :vert sb 1 | windo diffthis

Объяснение

  1. сначала открывает новую вкладку tabnewи загружает HEAD^в нее содержимое версии файла из буфера 1.
  2. открывает вертикальное разделение, содержащее буфер 1 с vert sb 1, затем выдает :diffthisвсе буферы на вкладке для перехода в режим сравнения.

Редактировать

OP запросил дополнительные объяснения на шаге 1. git showтребуется ввод формы, <rev>:<path>где <path>он должен быть относительно корня рабочего дерева. Например, если абсолютный путь к файлу в буфере 1 /a/b/foo.extтаков, что он bсодержит вашу .gitпапку (то есть bявляется корнем вашего репо), для git showправильной работы вам нужно будет вызвать его с помощью HEAD^:b/foo.e. Использование любого из них /a/b/foo.extили foo.extне сработает. Поэтому я использовал git rev-parse --show-prefixдля получения пути к текущей папке относительно корня git (который был бы b/) в этом примере.

Затем я использовал vimрасширение пути, чтобы добавить имя файла (то есть foo.ext). #1сообщает, что vimнужно получить путь к любому файлу, загруженному в буфер 1, и :tизвлекает "хвост", который представляет собой все, что находится после последнего /в пути, возвращаемом #1. В некоторых случаях #1и #1:tравны, но это не всегда так. Например, если вы побежали, vim b/foo.extто #1вернетесь, b/foo.extа не просто foo.ext. Проверьте :help expandдля получения дополнительной информации.

Конечно, вы можете просто ввести путь вручную, как в :tabnew | r! git show HEAD^:b/foo.ext, и это сработает. Но версия, приведенная выше, поддерживает скрипт или вы можете назначить ее на карту.