Как вычислить git-хеш-объект каталога? - PullRequest
14 голосов
/ 16 мая 2011

У кого-нибудь есть пример использования git hash-object в каталоге? Он работает достаточно легко для файла *, но не работает, как я ожидал для каталога **

*:  git hash-object c:\somefile.txt
**: git hash-object -t tree c:\somedirectory

Когда я пытаюсь использовать хеш-объект с каталогом, он жалуется: «Неустранимый: не удается открыть« C: \ someDirectory »: разрешение запрещено»

Ответы [ 6 ]

14 голосов
/ 16 мая 2011

git hash-object -t tree ожидает, что параметром файла будет файл, который описывает записи в дереве, а не каталог в файловой системе. Из комментария здесь я понимаю, что эта команда ожидает файл, который описывает дерево в двоичном формате, и что вам будет проще использовать git mktree для создания объекта дерева.

git mktree понимает ввод формата, который вы получаете (например) git ls-tree HEAD. Хороший пример создания дерева с нуля с использованием git hash-object и git mktree в Git Community Book .

4 голосов
/ 08 декабря 2017

В зависимости от того, почему вы хотите это сделать, может быть полезна следующая команда git:

git ls-files -s somedirectory | git hash-object --stdin

Это дает один хеш, который учитывает имена файлов и их содержимое.

Это работает так. git ls-files -s .... выводит список файлов и их хэши в виде текста в stdout, затем git hash-object генерирует хеш для данных, которые он получает от stdin.

Мой пример использования для этого следующий: я хочу знать, точно ли (* git) файлы в каталоге в одной ветви точно (*) совпадают с файлами в другой ветви. Конкретное использование для сравнения «хэшей каталогов» решает, нужно ли мне заново генерировать производные файлы, которые кэшируются.

По умолчанию git ls-files будет также перечислять файлы в подкаталогах. Если вы не хотите этого, попробуйте посмотреть ответы на вопрос "как создать git ls-файл для всего одного уровня каталога . Существуют также различные другие опции для git ls-files , включая возможность указать список файлов для включения.

(*), исключая коллизии хешей

2 голосов
/ 24 июня 2014

У меня была та же проблема, и я взломал скрипт Python для хеширования полного каталога . Он ограничен в том смысле, что он не учитывает файл .gitignore, но на данный момент он служит своей цели (хэш-каталог, объект make commit, хранит его в gh-pages ветви ).

1 голос
/ 19 июля 2016

Я бы хотел улучшить ответ @ Fred Foo , предоставив модифицированную версию его скрипта, отличающуюся тем, что он не хранит файлы и каталоги в репозитории как побочный эффектвычисление их хешей: http://pastebin.com/BSNGqsqC

К сожалению, я не знаю ни одного способа заставить git mktree не создавать объект дерева в хранилище, поэтому код должен генерировать двоичное представление дерева и передаватьэто git hash-object -t tree.

Этот сценарий также основан на ответах от Каков внутренний формат объекта дерева мерзавцев?

Основная идея заключается в использовании git hash-object -- data.txt, чтобы получить хеш файла и использовать git hash-object --stdin -t tree < TreeDescription для каталога, где:

  • TreeDescription - это конкатенация "mode name\0hash"
  • mode, равная "100644" для файлов и "40000" для каталогов (обратите внимание на отсутствие начального нуля в случае каталога)
  • mode и name разделяются одним пробелом,
  • name и hash разделены одним байтом \0
  • hash - это 20-байтовое двоичное представление хэша объекта
  • записи отсортированы по name, что не является абсолютно необходимым для создания объекта дерева, но помогает определить, эквивалентны ли две директории, сравнивая иххэши - к сожалению, я не знаю, какой алгоритм сортировки следует использовать здесь (в частности: что делать в случае символов, отличных от ascii)

Также обратите внимание, что этот двоичный формат немного отличается откак объект дерева хранится в хранилище, так как в нем отсутствует заголовок "tree SIZE\0".

Очевидно, что вам нужно вычислить этот восходящий, начиная с самых глубоких файлов, так как вам нужно хешировать все дочерние элементы перед вычислениемхеш родителя.

0 голосов
/ 30 апреля 2015

После долгих поисков я нашел следующую команду:

git write-tree

Источник: http://git -scm.com / документы / ГИТ-записи дерева

Я использовал его для восстановления отсутствующего каталога:

git write-tree path/to/missing/folder

И мой отсутствующий объект дерева создан. Отсюда вы можете продолжить использовать:

git hash-object -w path/to/missing/folder/file.txt

Как объяснено в: https://git.wiki.kernel.org/index.php/GitFaq#How_to_fix_a_broken_repository.3F

0 голосов
/ 18 марта 2014

Как сказал Марк Лонгэйр, mktree - это путь.

У меня была та же проблема, и мне пришлось много бороться, чтобы ее исправить. Вот что я сделал:

git ls-files -s directory_path

Это даст вам список содержимого каталога с его хешами.

Затем вы можете превратить этот список в формат ls-tree в текстовом редакторе и

echo -e "{ls-tree format list}" | git mkdir
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...