Git - поиск имени файла из SHA1

Я добавил файл в индекс с помощью:

git add somefile.txt

Затем я получил SHA1 для этого файла с:

git hash-object somefile.txt

Теперь у меня есть SHA1, и я хотел бы получить имя файла объекта в индексе, используя SHA1.

git show 5a5bf28dcd7944991944cc5076c7525439830122

Эта команда возвращает содержимое файла, но не имя файла.

Как я могу получить полное имя файла и путь назад от SHA1?

6 ответов

Решение

В git такого прямого сопоставления нет, поскольку имя файла является частью объекта дерева, содержащего файл, а не объекта blob, который является содержимым файла.

Это не обычная операция, когда нужно получить имя файла из хэша SHA1, так что, возможно, вы могли бы расширить его для реального использования?

Если вы просматриваете текущие файлы (т.е. коммит HEAD), вы можете попробовать следующее.

git ls-tree -r HEAD | grep <SHA1>

Если вы хотите найти содержимое предыдущих коммитов, вам нужно сделать что-то более похожее на это.

git rev-list <commit-list> | \
xargs -n1 -iX sh -c "git ls-tree -r X | grep <SHA1> && echo X"

Отличный лайнер для этого:

git rev-list --objects --all | grep <blob sha1>

Следующий сценарий оболочки в значительной степени основан на том, какой коммит имеет этот BLOB-объект? и ответ, предоставленный Аристотелем Пагальцисом.

#!/bin/sh

obj_hash=$1

# go over all trees
git log --pretty=format:'%T %h %s' \
| while read tree commit subject ; do
     git ls-tree -r $tree | grep  "$obj_hash" \
     | while read a b hash filename ; do
        if [ "$hash" == "$obj_hash" ]; then
          f=$filename
          echo $f
          break
        fi
        if $f ; then break; fi
      done
      if $f; then break; fi
done

Я уверен, что кто-то может украсить этот скрипт, но он работает. Идея состоит в том, чтобы просмотреть все зафиксированные деревья и найти ваш конкретный хеш.

git rev-list <commit-list> не будет содержать коммиты, которые были, например, удалены rebase -i и теперь на них ссылается только reflog, поэтому, если blob не найден командой выше, вы должны также проверить reflog, например, так:

git reflog --all | \
cut -d\  -f1 | \
xargs -n1 -iX sh -c "git ls-tree -r X | grep <BLOB_SHA> && echo X"

Расширяя комментарий @Harold к другому ответу, эта команда предоставит вам фиксацию, в которой был введен файл, и путь к файлу в фиксации:

      git describe --always <blob-hash>

Протестировано на git версии 2.30.2.

Зафиксируйте файл и запишите хэш sha1 объекта коммита. После этого использования

git ls-tree <commit-sha1>

и вы получите имена файлов с хэшами.

Проверьте справочные страницы для большего количества вариантов.

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