Сокращение для просмотра diff предыдущей версии файла
Я могу легко узнать, что изменилось для файла с момента последнего коммита с помощью git diff HEAD^ -- <filename>
, но есть ли эквивалентная сокращенная версия для просмотра diff для определенного файла с момента последнего его завершения, независимо от того, сколько из них произошло? Или вернуть N коммитов этого конкретного файла?
Контекст: Я обнаружил ошибку в файле, и я хочу отслеживать ее при загрузке. Достаточно легко получить отчет журнала для определенного файла с git log -<n> <filename>
, чтобы показать только которые включали изменения в этот файл. Поэтому я могу просто скопировать и вставить SHA из этого отчета log
, но я действительно хочу, чтобы иметь возможность делать что-то вроде git diff ^ -- <filename>
или git diff ~2 -- <filename>
.
Ответы
Ответ 1
$ git log -p <filename>
покажет вам сообщение журнала плюс diff для каждой фиксации, которая коснулась именованного файла.
Чтобы показать только отличия от предыдущей версии, попросите только один шаг в истории журнала:
$ git log -1 -p <filename>
Ответ 2
Вы можете использовать форматирование git log
, чтобы получить хэши предыдущих коммитов в файл. Например,
git log --pretty=format:'%h' -1 --skip=1 <filename>
вы получите второе от последнего фиксацию, чтобы коснуться определенного файла. На самом деле, если вы не укажете имя файла, это даст вам второе-последнее коммит во всем репозитории. Чтобы получить старые хэши, вы можете настроить псевдоним git, который вызывает функцию оболочки, например:
[alias]
prior-hash = "!ph() { git log --pretty=format:'%h' -1 --skip=$1 $2; }; ph"
Чтобы использовать его, вы должны ввести что-то вроде git prior-hash n <filename>
, где n является (n + 1) -й самой последней версией файла. Таким образом, 1 будет вторым последним фиксацией файла, 2 будет последним, и т.д., А 0 - последним фиксатором для касания этого файла. И снова, имя файла является необязательным, если вы хотите изучить репо в целом.
Я уверен, что вы могли бы выяснить, как построить команду diff отсюда:
[alias]
prior-hash = "!ph() { git log --pretty=format:'%h' -1 --skip=$1 $2; }; ph"
diff-prev-easy = "!dp() { git diff $(git prior-hash $1 $2).. $2; }; dp"
который будет использоваться аналогично псевдослучайному хэшу, git diff-prev-easy n <filename>
. Это сопоставило бы (n + 1) -ую последнюю ревизию с последней версией файла. Если вы захотите сравнить (n + 1) -ю последнюю ревизию с последней версией n, это простое изменение:
[alias]
prior-hash = "!ph() { git log --pretty=format:'%h' -1 --skip=$1 $2; }; ph"
diff-prev = "!dp() { git diff $(git prior-hash $1 $2)..$(git prior-hash $(($1 - 1)) $2) $2; }; dp"
который, опять же, используется таким же образом: git diff-prev n <filename>
Одна из потенциальных проблем, которые следует учитывать, состоит в том, что списки git log
фиксируются в хронологическом порядке, что может и не быть тем, что вы хотите. Рассмотрим эту историю:
1 - 2 - - - 4 - 5 master
\ /
3 - - develop
Наша команда git diff-prev 1
создаст разницу между фиксацией 4 и 5, как и ожидалось. Но git diff-prev 2
будет показывать разницу между фиксацией 3 и 4, что, вероятно, нежелательно.
Ответ 3
git blame
должен быстро доставить вас в пункт назначения.