Когда git действительно проверяет целостность цепочки коммитов?

Я много раз читал о механизме целостности в git, основанном на хэшах SHA-1 и ссылках на родительские коммиты, что гарантирует отсутствие изменений в зафиксированных данных в репозитории git.

Мой вопрос: во время каких операций git проверяет правильность хэшей, т.е. е. соответствовать содержанию коммитов? Выполняется ли проверка во время push или, может быть, pull? К сожалению, никакой информации по этому поводу я не нашел.


person Jeff S.    schedule 01.06.2018    source источник
comment
Поскольку каждая сумма SHA1 фактически соответствует одному объекту, то есть отдельному сжатому файлу, я предполагаю, что сумма, вероятно, пересчитывается на лету каждый раз, когда этот файл записывается на диск или когда он полностью читается, путем мониторинга поток данных. Это включает в себя отправку, когда вы это делаете, извлечение с удаленного сервера, когда вы их получаете, когда вы выполняете git checkouts или любую команду, которая применяется к объекту, например git show. Это то, что я лично сделал бы.   -  person Obsidian    schedule 01.06.2018


Ответы (1)


комментарий Obsidian является точным -on: имя каждого объекта Git является хэш-идентификатором содержимого объекта, поэтому все, что использует идентификатор для поиска и чтения содержимого, может и обычно делает это для проверки того, что хэш извлеченные данные соответствуют идентификатору, используемому в качестве ключа для извлечения этих данных.

Дополнительная проверка — подтверждение того, что подпись GPG в теге или коммите — выполняется только тогда, когда вы специально запрашиваете ее. Вы можете запросить git log проверку таких подписей по умолчанию, используя параметр конфигурации log.showSignature.

Обратите внимание, что целостность любого узла в дереве Меркла зависит от того, доверяете ли вы предыдущим узлам относительно вторых. -прообразные атаки. Если вы используете теги, подписанные GPG, подписи в этих тегах защищают данные каждого тега (в какой бы степени вы ни доверяли самой GPG), а затем тег защищает свой объект фиксации (в какой бы степени вы ни доверяли SHA-1). Объект фиксации, в свою очередь, защищает свое дерево, которое защищает его поддеревья и большие двоичные объекты, а хэши больших двоичных объектов защищают их содержимое. Поэтому вам следует провести другой вид анализа, если вас интересуют атаки второго прообраза. Если вы просто обеспокоены случайным повреждением данных (как видно на вращающемся носителе и/или в памяти без ECC), вы можете просто использовать хэш SHA-1 напрямую, как это делает Git.

person torek    schedule 01.06.2018
comment
Хорошо, спасибо за подробный ответ. Полезно знать, что хэши проверяются практически любыми операциями над хэшированными объектами. Я удивлен, я не нашел этой информации в официальной документации, но, возможно, это рассматривается как деталь реализации. - person Jeff S.; 04.06.2018
comment
Можно я добавлю глупый вопрос? Проверяет ли он также, что файлы не были повреждены, например, во время git clone? Если я храню какой-то большой файл в репозитории git, должен ли я вручную выполнять некоторые проверки контрольной суммы после git clone или я уверен, что все в порядке, если при клонировании не было ошибок? - person Nikita Popov; 12.12.2020
comment
@NikitaPopov: все в Git хранится как объект. У каждого объекта есть хэш-идентификатор, который мы вычисляем, используя своего рода контрольную сумму (в настоящее время SHA-1, но в Git 2.29 уже есть поддержка прототипов для других алгоритмов хеширования). Git хранит не файлы, а только эти объекты. Код извлечения должен сообщить хэш-идентификатор, потому что именно так мы ищем объект в базе данных ключей и значений, в которой они хранятся. Затем код извлечения снова вычисляет хэш во время извлечения. Этот должен соответствовать ключу, используемому для поиска объекта. Если это так, объект не поврежден. - person torek; 12.12.2020
comment
Фактическая повторная проверка хэш-идентификаторов объектов во время git clone немного отложена, но это детали реализации: git clone состоит из шести шагов, пятым шагом является git fetch, который получает все достижимые объекты. Отправитель может отправлять эти объекты по одному, и в этом случае они будут проверяться по мере поступления в хранилище, но это ужасно медленно, поэтому современные протоколы отправляют так называемый pack-файл с дельта-данными. сжатые объекты в нем. Затем принимающий Git запускает пакетный индексатор, который считывает и проверяет все объекты. Следовательно, клон находит любые ошибки во время индексации. - person torek; 12.12.2020