TL; DR
Учитывая, что вы знаете хеш коммита <hash>
, вы, вероятно, захотите:
git diff-tree --find-renames -r --name-status --diff-filter=R --no-commit-id <hash>
или то же самое с добавлением -z
. Вы также можете указать (первого) родителя слияния, в этом случае --no-commit-id
не требуется.
Long
Есть несколько способов сделать это в зависимости от различных деталей о том, что вы хотите для вывода. Ключ должен начинаться с предсказуемой команды plumbing . В Git сантехническая команда - это команда, которая по существу предназначена для использования какой-либо другой программой, так что она имеет машиночитаемый, предсказуемый, надежный формат вывода. Теперь вы получаете вывод git diff --summary
, а git diff
- команду фарфор , предназначенную для чтения человеком:
$ git diff --summary 99177b34db^ 99177b34db
rename contrib/hooks/multimail/{README => README.rst} (95%)
, который git show --summary
выполняется в конце других своих операций.
Для механически разбираемого вывода мы можем переключиться на git diff-tree
. Если нам нужны имена и статусы каждого измененного файла, мы можем запросить это:
$ git diff-tree --name-status -r 99177b34db^ 99177b34db
M contrib/hooks/multimail/CHANGES
M contrib/hooks/multimail/CONTRIBUTING.rst
D contrib/hooks/multimail/README
M contrib/hooks/multimail/README.Git
A contrib/hooks/multimail/README.rst
M contrib/hooks/multimail/doc/gitolite.rst
M contrib/hooks/multimail/git_multimail.py
M contrib/hooks/multimail/migrate-mailhook-config
M contrib/hooks/multimail/post-receive.example
Мы сразу видим, что здесь есть недостаток: мы не наблюдали переименования. Это связано с тем, что между (первым и единственным) родителем коммита 99177b34db
(99177b34db^
) и самого коммита 99177b34db
фактического переименования не было. Два снимка имеют только два набора файлов. Переименование, которое мы видим, является догадкой , которое git diff --summary
делает. Чтобы поручить Git делать то же предположение при использовании git diff-tree
, мы должны добавить --find-renames
- что позволяет us выбрать порог сходства, который считается переименованием, но по умолчанию равен тем же 50%, которые мы получаем за резюме:
$ git diff-tree --find-renames --name-status -r 99177b34db^ 99177b34db
M contrib/hooks/multimail/CHANGES
M contrib/hooks/multimail/CONTRIBUTING.rst
M contrib/hooks/multimail/README.Git
R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
M contrib/hooks/multimail/doc/gitolite.rst
M contrib/hooks/multimail/git_multimail.py
M contrib/hooks/multimail/migrate-mailhook-config
M contrib/hooks/multimail/post-receive.example
Эта строка R095
содержит то, что мы хотим: обнаруженное переименование, значение сходства (в данном случае 95%) и оба имени файла, в данном случае разделенные табуляцией.
Мы можем использовать --diff-filter
, чтобы уменьшить вывод и включить только переименования:
$ git diff-tree --find-renames --name-status -r --diff-filter=R 99177b34db^ 99177b34db
R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
Обратите внимание, что мы можем запустить git diff-tree
только с одним хэшем коммита. Это хорошо работает, когда коммит является обычным (без слияния):
$ git diff-tree --find-renames --name-status -r --diff-filter=R 99177b34db
99177b34db1d473e8f90544cf0bf83f47308e9ad
R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
Однако теперь мы получаем полный идентификатор хэша в выводе. Добавление --no-commit-id
говорит, что он не должен включать хеш-код.
Это также работает иначе , если указанный нами коммит является коммитом слияния. Я не собираюсь иллюстрировать это здесь, так как у меня нет удобного слияния, чтобы смотреть на это так, но обратите пристальное внимание на описание документации формата diff для слияний и отдельное примечание о комбинированном формате , которое говорит нам, что иногда мы вообще не видим некоторые файлы.
Отбрасывание --name-status
дает нам этот другой формат, более длинный и иногда более полезный:
$ git diff-tree --find-renames -r --diff-filter=R 99177b34db^ 99177b34db
:100644 100644 5105373aea044f2d8fde0c4fd927c8c492d02585 7c0fc4a6ef00362dcff476497a6045a420562d05 R095 contrib/hooks/multimail/README contrib/hooks/multimail/README.rst
Здесь мы получаем хэши BLOB-объектов двух файлов с двумя режимами (100644
) перед ними, все с префиксом одного двоеточия :
. Детали изменились бы, если бы мы получили вывод для коммита слияния.
Во всех этих случаях вы можете добавить опцию -z
. Это изменяет выходные данные, чтобы сделать их еще более машиночитаемыми (но очень нечитаемыми человеком): различные части каждой выходной записи имеют байты ASCII NUL (0x00) для их разделения. Эта опция также описана в документации вместе с некоторыми подробностями того, какие изменения вносятся в имена путей, когда вы не используете -z
.