Как я могу запустить `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 привязки применяются только к файлу в текущей строке и, следовательно, не могут по определению использоваться для просмотра всех поэтапных изменений. Кроме того, :GstatusD Привязка даже не просматривает все подготовленные изменения для файла в текущей строке. Он только различает индекс и копии рабочего дерева этого файла, а не только индекс и самые последние зафиксированные копии этого файла (который является совершенно другим зверем).

:Gdiff HEAD аналогично неприменим. Он отображает только самые последние сохраненные и рабочие копии дерева, соответствующие текущему буферу. :Gdiff без аргумента эквивалентно :GstatusD привязка, снова разметка индекса и рабочие копии дерева этого файла. Ни один из обзоров не все постановочные изменения.

Применимые ответы

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 вернуться.

объяснение

  1. Gtabedit откройте новую вкладку и отредактируйте беглый объект:
    • от коммита @ (HEAD), конкретный файл :текущий файл %,
  2. Gdiff diff текущий буфер против другого беглого объекта:
    • из индекса : (вы можете указать файл снова с помощью :% но это не нужно).

бонус

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

Рекомендации

Как уже отмечалось, Gdiff, Gdiff : или же Gdiff :0 дает вам разницу с индексом,Gdiff - или же Gdiff HEAD дает разницу с ГОЛОВОЙ.

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

Так что делать различий сначала с : затем с - показать 3 панели в VIM:

  1. ГОЛОВА
  2. индекс ("кэшированный" или "поэтапный")
  3. рабочее дерево
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>, не как .

  1. Разница между последней фиксацией и проиндексированными изменениями, за исключением непроиндексированных изменений. т. е. что на самом деле было бы зафиксировано, если бы вы запустили прямо сейчас (без-a). Это ответ на исходный вопрос, как написано:

    git diff --staged <current_file>илиgit diff --cached <current_file>

    Gtabedit :0 | Gdiffsplit @:#илиGtabedit @:% | Gdiffsplit :0

    (2vim-fugitiveварианты здесь просто меняют порядок окон)

  2. Разница между рабочим каталогом (неустановленным) и поэтапными изменениями. т.е. что будет добавлено в индекс, если вы запуститеgit add <current_file>прямо сейчас:

    git diff <current_file>

  3. Разница между всеми изменениями (проиндексированными и непроиндексированными) и последней фиксацией. т.е. что бы было зафиксировано, если бы вы запустилиgit commit -aпрямо сейчас:

    git diff HEAD -- x

    Gdiffsplit HEAD

Примечание:git commitприведенные выше команды будут включать другие отслеживаемые файлы


ПРИМЕЧАНИЕ. Зачем нужен еще один ответ?

  • Предыдущие ответы сбивают с толкуgit diff --stagedсgit diff HEAD(это можно увидеть, если у вас есть проиндексированные и непроиндексированные изменения)
  • В этом ответе показано, как открыть фактическое окно различий vim в текущем сеансе vim для каждого типа различий (т. е. фактическое поведениеGdiffт.е.Gdiffsplitкак изначально и просили)

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

: Gdiff --staged

Сделаю..:)

Другие вопросы по тегам