Сокращение для просмотра различий предыдущей версии файла
Я могу легко узнать, что изменилось для файла с момента последнего коммита с git diff HEAD^ -- <filename>
но есть ли эквивалентное сокращение для просмотра различий для конкретного файла с момента его последнего принятия, независимо от того, сколько подтверждений произошло с тех пор? Или вернуться назад N коммитов этого конкретного файла?
Контекст: я нашел ошибку в файле, и я хочу отследить, когда она проникла внутрь. Достаточно легко получить отчет журнала для определенного файла с git log -<n> <filename>
показывать только те коммиты, которые включали изменения в этот файл. Ясно, что я могу просто скопировать и вставить SHA из этого log
отчет, но я действительно хочу иметь возможность сделать что-то вроде git diff ^ -- <filename>
или же git diff ~2 -- <filename>
,
3 ответа
$ git log -p <filename>
покажет вам сообщение журнала плюс diff для каждого коммита, который коснулся названного файла.
Чтобы показать только отличия от предыдущей версии, запросите только один шаг в истории журнала:
$ git log -1 -p <filename>
Вы можете использовать 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-м последним коммитом в файл, 2 будет 3-м последним коммитом и т. Д., А 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, что, вероятно, нежелательно.
git blame
должен доставить вас к месту назначения довольно быстро.