Как я могу запустить `git diff --staged` с помощью Fugitive?

Команда :Gdiff эквивалентна выполнению git diff для этого файла.

Что эквивалентно git diff --staged или git diff --cached?


person Flimm    schedule 14.03.2013    source источник


Ответы (7)


Я нашел способ сделать это. Запустите :Gstatus, вы должны получить окно со следующим содержимым:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   example.txt
#

Прокрутите вниз до подготовленного файла example.txt и нажмите Shift+D. Это откроет представление различий, сравнивая то, что находится в HEAD, и то, что находится в индексе. Вы заметите на панели внизу, что оба имени файла являются специальными именами Fugitive.

Также, находясь в окне предварительного просмотра Gstatus, вы можете нажать g?, что отобразит список всех сопоставлений, действительных в текущем контексте.

person Flimm    schedule 22.08.2014
comment
:Gstatus D устарел в пользу dd - person jmm; 05.06.2020
comment
@jmm Да, я тоже получил это сообщение, но что оно означает? dd в обычном режиме удаляет строку. И :Gstatus, за которым следует dd, делает что-то другое. - person Konrad Rudolph; 10.09.2020

Хотя 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. Никакого Виммьера получить не удалось.

person Cecil Curry    schedule 05.04.2015
comment
Эта команда :Greview должна быть частью vim-fugitive! - person jackyalcine; 21.01.2016
comment
Это отлично подходит для просмотра всех изменений в одном буфере, спасибо! Есть ли простой способ открыть каждый подготовленный файл в режиме просмотра различий на отдельной вкладке? - person Achal Dave; 20.02.2017
comment
Привет! Я не знаю, как легко и просто вернуться к этому файлу tmp, поэтому мой обходной путь был command Greview :Gtabedit! diff --staged - person ssaid; 25.09.2017
comment
Следует отметить, что для одного файла это то же самое, что и dd в этой строке. - person TamaMcGlinn; 13.11.2020

:Gdiff HEAD

Gdiff принимает аргумент ревизии. Так что можете пройти HEAD. Это не эквивалентно git diff --staged, но может служить аналогичной цели.

person Flimm    schedule 18.07.2013
comment
Другой способ — использовать :Git diff --staged, потому что :Git эквивалентно команде git. - person emaniacs; 21.08.2014
comment
@emaniacs: это не открывает diff с использованием функциональности Vim diff, как это делает :Gdiff. - person Flimm; 22.08.2014

Обновление: 28.03.2017,

Текущая версия fugitive сделает это автоматически, когда вы нажмете D на файле.

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

person BenJamin    schedule 29.03.2017

Как уже отмечалось, Gdiff, Gdiff : или Gdiff :0 дает вам diff с индексом, Gdiff - или Gdiff HEAD дает diff с HEAD.

Тройной подход

Итак, выполняя diff сначала с :, а затем с -, покажите 3 панели различий в vim:

  1. ГЛАВА
  2. индекс («кэшированный» или «поэтапный»)
  3. рабочее дерево
command! -bar Gvstage :Gvdiff -|Gvdiff : " vertical 3-split
command! -bar Gsstage :Gsdiff -|Gsdiff : " horizontal 3-split

Конечно, вы также можете просто Gvdiff -, если вы уже находитесь в режиме diff.

Теперь отправка и получение изменений немного сложнее с 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, но имеет тот недостаток, что вы не можете редактировать промежуточный файл.

person Cimbali    schedule 10.11.2017

Используйте 1_.

Это лучше, чем другие ответы, потому что он открывается в разделенном представлении, как :Gdiff, а не сбрасывает синтаксис diff в один буфер. Когда вы закончите, просто :tabc вернуться.

Объяснение

  1. Gtabedit open a new tab and edit a fugitive object:
    • from commit @ (HEAD), a specific file :, the current file %.
  2. Gdiff diff the current buffer against another fugitive object:
    • from the index : (you can specify the file again with :% but it's not needed).

Бонус

Теперь у нас есть беглые эквиваленты для git diff (:Gdiff) и git diff --staged (команда выше). Чтобы получить поведение git show в текущем файле, используйте :Gtabedit @~:% | Gdiff @.

использованная литература

person mk12    schedule 14.12.2018

В случае, если вы кто-то наткнулся на этот вопрос.

:Gdiff --постановка

Сделаю.. :)

person notmii    schedule 18.07.2013
comment
Боюсь, это не работает для меня. Но это помогло мне найти правильный ответ, так что спасибо за помощь! - person Flimm; 18.07.2013