Как я могу запустить `git diff --staged` с Fugitive?
Команда :Gdiff
эквивалентно бегу git diff
в этом файле.
Что эквивалентно для git diff --staged
или же git diff --cached
?
8 ответов
Я нашел способ сделать это. Бежать :Gstatus
, вы должны получить окно с содержимым вроде следующего:
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: example.txt
#
Прокрутите вниз до промежуточного файла, example.txt
и нажмите Shift+D. Это откроет представление diff, сравнивая, что находится в HEAD и что находится в индексе. На панели внизу вы заметите, что оба имени файла являются специальными именами.
Также в окне предварительного просмотра Gstatus вы можете нажать g?, который перечислит все сопоставления, действительные в текущем контексте.
В то время как vim-fugitive
не поставляет прямые аналоги для git diff --staged
или же git diff --cached
, он предоставляет универсальную команду Vim для передачи результатов произвольного git
Команды в буферы Vim только для чтения::Git!
,
Неприменимые ответы
Прежде чем мы перейдем к этому, давайте еще раз сформулируем вопрос.git diff --staged
а такжеgit diff --cached
являются синонимами для одной и той же базовой операции: дифференцирование содержимого индекса (набора всех поэтапных изменений) с содержимым HEAD (самой последней фиксации для текущей ветви), обычно для просмотра изменений перед фиксацией. Поставленный вопрос тогда становится:
Что является наиболее эффективным средством проверки всех поэтапных изменений в
vim-fugitive
?
Должно быть ясно, что в настоящее время принятый ответ не решает этот вопрос. Следующий самый высокий рейтинг самоотдачи не лучше.
:Gstatus
привязки применяются только к файлу в текущей строке и, следовательно, не могут по определению использоваться для просмотра всех поэтапных изменений. Кроме того, :Gstatus
D
Привязка даже не просматривает все подготовленные изменения для файла в текущей строке. Он только различает индекс и копии рабочего дерева этого файла, а не только индекс и самые последние зафиксированные копии этого файла (который является совершенно другим зверем).
:Gdiff HEAD
аналогично неприменим. Он отображает только самые последние сохраненные и рабочие копии дерева, соответствующие текущему буферу. :Gdiff
без аргумента эквивалентно :Gstatus
D
привязка, снова разметка индекса и рабочие копии дерева этого файла. Ни один из обзоров не все постановочные изменения.
Применимые ответы
emaniacs ударил ближе всего к рабочему решению с этим комментарием к последнему ответу:
:Git diff --staged
Теперь мы приближаемся к истине!
:Git
трубы на выходе прошли git
Команда на текущий внешний пейджер, позволяющая лживо просмотреть все промежуточные изменения, внешние по отношению к Vim. Но есть загвоздка: внешняя по отношению к Vim. Это означает отсутствие привязок Vim, буферов или подсветки синтаксиса. В идеале, мы бы предпочли синтаксис буфера Vim только для чтения, выделяющий вывод git diff --staged
, Можем ли мы сделать это?
Решение
Мы можем, или Тим Поуп не Вим Папа. !
суффиксный вариант :Git
делает это, позволяя лживо просматривать все поэтапные изменения в Vim в комплекте с подсветкой синтаксиса различий изменений на основе Vim:
:Git! diff --staged
Да уж. Это довольно круто.
Но давайте пойдем на шаг дальше. В давней традиции ленивых бездельников повсюду давайте определим новую команду Vim :Greview
инкапсуляция этой операции и нового связывания <leader>gr
запустить эту команду. Просто спрятать следующее в свой .vimrc
:
command Greview :Git! diff --staged
nnoremap <leader>gr :Greview<cr>
Если предположить, <leader>
быть ,
, просмотр всех поэтапных изменений сводится к ,gr
, Это не могло получить никакого Vimmier.
:Gdiff HEAD
Gdiff
принимает аргумент пересмотра. Таким образом, вы можете передать его HEAD
, Это не эквивалентно git diff --staged
, но это может служить аналогичной цели.
Использование :Gtabedit @:% | Gdiff :
,
Это лучше, чем другие ответы, потому что он открывается в разделенном виде, как :Gdiff
вместо сброса синтаксиса diff в один буфер. Когда вы закончите, просто :tabc
вернуться.
объяснение
Gtabedit
откройте новую вкладку и отредактируйте беглый объект:- от коммита
@
(HEAD), конкретный файл:
текущий файл%
,
- от коммита
Gdiff
diff текущий буфер против другого беглого объекта:- из индекса
:
(вы можете указать файл снова с помощью:%
но это не нужно).
- из индекса
бонус
Теперь у нас есть беглые эквиваленты для git diff
(:Gdiff
) а также git diff --staged
(команда выше). Чтобы получить поведение git show
в текущем файле используйте :Gtabedit @~:% | Gdiff @
,
Рекомендации
- https://github.com/tpope/vim-fugitive/issues/837
:help fugitive-object
Как уже отмечалось, Gdiff
, Gdiff :
или же Gdiff :0
дает вам разницу с индексом,Gdiff -
или же Gdiff HEAD
дает разницу с ГОЛОВОЙ.
Тройной подход
Так что делать различий сначала с :
затем с -
показать 3 панели в VIM:
- ГОЛОВА
- индекс ("кэшированный" или "поэтапный")
- рабочее дерево
command! -bar Gvstage :Gvdiff -|Gvdiff : " vertical 3-split
command! -bar Gsstage :Gsdiff -|Gsdiff : " horizontal 3-split
Конечно, вы также можете просто Gvdiff -
если вы уже в режиме сравнения.
Теперь сдвинуть и получить изменения немного сложнее с 3 открытыми окнами, однако, вы можете diffput
от индекса к рабочему дереву и наоборот легко, как на HEAD modifiable
выключен, поэтому он никогда не может быть целью
В противном случае вы можете добавить несколько ярлыков для diffput
а также diffget
команды, зная, что они могут принимать "спецификатор буфера", который может быть шаблоном (см.: help merge) или номером буфера. Я изменил предыдущие команды, чтобы сохранить начальный номер буфера и использовать шаблоны для других:
command! -bar Gvstage :let t:working_copy=bufnr('%')|Gvdiff -|Gvdiff : " vertical 3-split
command! -bar Gsstage :let t:working_copy=bufnr('%')|Gsdiff -|Gsdiff : " horizontal 3-split
nnoremap <Leader>hg :diffget fugitive://*/.git//[0-9a-f][0-9a-f]*/<CR> " HEAD get
nnoremap <Leader>ig :diffget fugitive://*/.git//0/<CR> " index get
nnoremap <Leader>ip :diffput fugitive://*/.git//0/<CR> " index put
nnoremap <Leader>wg :diffget <C-R>=t:working_copy<CR><CR> " work get
nnoremap <Leader>wp :diffput <C-R>=t:working_copy<CR><CR> " work put
Difftool подход
С другой стороны, если вы просто хотите хороший vimdiff
просмотр того, что ставится вместо патча, позвольте мне подсказать:
command! Greview :exec "Git difftool --tool=vimdiff --staged " . fugitive#buffer().path()
Это запускает новый экземпляр vim, поэтому, когда вы выходите из него, вы возвращаетесь к своим вкладкам и окнам, которые вы уже открыли, что идеально. Это если быстрее (по крайней мере для меня), чем переход через окно состояния git, но имеет недостаток в том, что вы не можете редактировать промежуточный файл.
Обновление: 28.03.2017,
Текущая версия беглеца будет делать это автоматически, когда вы нажимаете D
на файл.
если файл является поэтапным, в diff будут отображаться только поэтапные изменения. Если файл не подготовлен, то будут видны только те изменения, которые не подготовлены.
TLDR:
Объяснение:
Есть 3 соответствующих различия, когда у вас есть как проиндексированные, так и непроиндексированные изменения. Ниже показаны каждый из тех, у когоgit
и . Все команды открывают фактические различия vim в текущем сеансе редактора.
NB: ведет себя какgit diff HEAD -- <current_file>
, не как .
Разница между последней фиксацией и проиндексированными изменениями, за исключением непроиндексированных изменений. т. е. что на самом деле было бы зафиксировано, если бы вы запустили прямо сейчас (без
-a
). Это ответ на исходный вопрос, как написано:git diff --staged <current_file>
илиgit diff --cached <current_file>
Gtabedit :0 | Gdiffsplit @:#
илиGtabedit @:% | Gdiffsplit :0
(2
vim-fugitive
варианты здесь просто меняют порядок окон)Разница между рабочим каталогом (неустановленным) и поэтапными изменениями. т.е. что будет добавлено в индекс, если вы запустите
git add <current_file>
прямо сейчас:git diff <current_file>
Разница между всеми изменениями (проиндексированными и непроиндексированными) и последней фиксацией. т.е. что бы было зафиксировано, если бы вы запустили
git commit -a
прямо сейчас:git diff HEAD -- x
Gdiffsplit HEAD
Примечание:git commit
приведенные выше команды будут включать другие отслеживаемые файлы
ПРИМЕЧАНИЕ. Зачем нужен еще один ответ?
- Предыдущие ответы сбивают с толку
git diff --staged
сgit diff HEAD
(это можно увидеть, если у вас есть проиндексированные и непроиндексированные изменения) - В этом ответе показано, как открыть фактическое окно различий vim в текущем сеансе vim для каждого типа различий (т. е. фактическое поведение
Gdiff
т.е.Gdiffsplit
как изначально и просили)
В случае, если вы кто-то наткнулся на этот вопрос.
: Gdiff --staged
Сделаю..:)