Подтвердить что ты не робот

Как вычислить хэш-объект git каталога?

Есть ли у кого-нибудь пример использования хэш-объекта git в каталоге? Он работает достаточно легко в файле *, но не работает так, как я ожидал бы для каталога **

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

Когда я пытаюсь использовать хэш-объект с каталогом, он жалуется "фатальный: не может открыть" C:\someDirectory: Permission denied "

4b9b3361

Ответ 1

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

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

Ответ 3

В зависимости от того, зачем вы это делаете, может понадобиться следующая команда 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, включая возможность указать список файлов для включения.

(*), исключая хеш-столкновения

Ответ 4

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

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

git ls-files -s directory_path

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

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

echo -e "{ls-tree format list}" | git mkdir

Ответ 5

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

git write-tree

Источник: http://git-scm.com/docs/git-write-tree

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

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

Ответ 6

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

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

Этот script основан также на ответах Что такое внутренний формат дерева git?

Общая идея состоит в том, чтобы использовать 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 байтов объекта hash Записи
  • сортируются по name, что кажется не совсем необходимым для создания древовидного объекта, но помогает определить, эквивалентны ли два каталога, сравнивая их хэши - к сожалению, я не знаю, какой алгоритм сортировки следует использовать здесь (в в частности: что делать в случае символов, отличных от ascii)

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

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