Git diff файл против его последнего изменения

236

Возможно ли заставить git создавать diff между определенным файлом, как он существует сейчас, и как он существовал до последнего коммита, который его изменил?

То есть если мы знаем:

$ git log --oneline myfile
123abc Fix some stuff
456def Frobble the foos
789dba Initial commit

Затем git diff 456def myfileпоказывает последнее изменение в мой файл. Возможно ли сделать то же самое без знания, созданного git log; что изменилось в 123abc?

Chowlett
источник
8
Я предпочитаю использоватьgit diff HEAD^ <file_path>
просит
4
@asgs - не делать то , что я просил (по двум причинам - HEAD^это 123abc, HEAD^^есть 456def, и , если есть другие коммиты , которые не влияют на этот файл , то HEAD^относится к ним)
Chowlett
Вы правы, пропустили часть «последнего коммита, которая его изменила»
спрашивает

Ответы:

216

Это существует, но на самом деле это особенность git log:

git log -p [--follow] [-1] <path>

Обратите внимание, что -pтакже можно использовать для показа встроенного diff из одного коммита:

git log -p -1 <commit>

Используемые параметры:

  • -p(также -uили --patch) скрыт deeeeeeeep на git-logстранице руководства и фактически является опцией отображения git-diff. Когда используется с log, он показывает патч, который будет сгенерирован для каждого коммита , вместе с информацией о коммите - и скрывает коммиты, которые не касаются указанного <path>. (Это поведение описано в параграфе --full-diff, который приводит к отображению полного различий каждого коммита.)
  • -1показывает только самое последнее изменение указанного файла ( -n 1может использоваться вместо -1); в противном случае отображаются все отличные от нуля различия этого файла.
  • --follow требуется, чтобы увидеть изменения, которые произошли до переименования.

Насколько я могу судить, это единственный способ сразу увидеть последний набор изменений, внесенных в файл, без использования git log (или аналогичного) подсчета количества промежуточных ревизий или определения хэша фиксации.

Чтобы увидеть более ранние изменения ревизий, просто прокрутите журнал или укажите коммит или тэг, с которого нужно начать журнал. (Конечно, указание коммита или тега возвращает вас к исходной проблеме выяснения, что такое правильный коммит или тег.)

Кредит, где кредит должен:

  • Я обнаружил log -pблагодаря этому ответу .
  • Благодарим FranciscoPuga и этот ответ за показ мне --followварианта.
  • Благодарим КрисБетти за упоминание -n 1варианта и Ататко за упоминание -1варианта.
  • Благодарим sweaver2112 за то, что он заставил меня прочитать документацию и выяснить, что -p«означает» семантически.
Кайл Стрэнд
источник
6
Это было отличное решение для меня. Показывал каждый коммит и его отличия от текущего файла при запускеgit log -p filename
Ian Jamieson
4
Отлично. Чтобы увидеть только последнее изменение, это так же просто, как добавить -n 1параметр. git log -p -n 1 filename
Крис Бетти
@ChrisBetti Спасибо; Я включил это в свой ответ!
Кайл Стрэнд
1
-n 1также можно заменить на -1, это не меняет результат, я просто предпочитаю синтаксис:git log -p -1 filename
atatko
1
есть полезная опция "--skip = [n]". Вы можете напечатать, git log -p -1 --skip=1 <path>чтобы отобразить второй коммит.
Maciek
220

Один из способов использовать git diff:

git diff <commit> <path>

И общий способ отсылки одного коммита последнего коммита - это относительный путь к фактическому заголовку. Вы можете ссылаться на предыдущие коммиты как HEAD ^ (в вашем примере это будет 123abc) или HEAD ^^ (456def в вашем примере) и т. Д ...

Итак, ответ на ваш вопрос:

git diff HEAD^^ myfile
Франциско Пуга
источник
6
О Конечно. Я пытался HEAD^, но, конечно, это ничего не дало. Не думал попробовать HEAD^^.
Чоулетт
17
Может быть, более простой синтаксис для давно совершенных HEAD~2
коммитов
19
Это не так (по крайней мере, для Git 1.9.0), что HEAD^^ myfileфактически будет ссылаться на измененный второй-последний коммит myfile; это будет относиться ко всему последнему коммиту. Есть ли способ указать «Я хочу увидеть последнее изменение, внесенное в этот файл», не указав (часть) хеша коммитов или не посчитав количество коммитов между последним изменением, внесенным в этот файл, и текущей ревизией?
Кайл Стрэнд,
3
Хм, похоже, git log -pдовольно близко.
Кайл Стрэнд
30
причина понижения: вопрос задает вопрос «между конкретным файлом, каким он существует сейчас, и тем, каким он существовал до последнего изменения, которое его изменило », но если файл не был изменен во время последнего общего принятия, этот ответ не работает.
Крис Бетти
8

Если вы хорошо используете графический инструмент, это работает очень хорошо:

gitk <file>

gitk теперь показывает все коммиты, где файл был обновлен. Отметка коммита покажет вам разницу с предыдущим коммитом в списке. Это также работает для каталогов, но затем вы также можете выбрать файл для сравнения для выбранного коммита. Супер полезно!

Мартин Г
источник
1
Также очень полезно: git difftool HEAD^ fileилиgit difftool -d HEAD^ path
ForeverLearning