Целостность данных в Git?

Я уже слышал это несколько раз, что Git обеспечивает целостность данных. Но что это значит?

Я понимаю, что все объекты в Git доступны с помощью контрольной суммы SHA-1 и что эта контрольная сумма вычисляется на основе содержимого файла. Это означает, что если файл имеет изменения, вы получите разную контрольную сумму.

Но как это обеспечивает целостность данных? Если я найду некоторые данные на основе контрольной суммы (ключа), Git вернет ошибку, если ее не обнаружит (если она каким-то образом повреждена). Я предполагаю, что данные могут портиться при использовании Git - ошибок чтения диска и т.д.

Не вижу разницы, например. SVN здесь или как обеспечивается целостность данных практически в Git.

Ответ 1

Если я ищу некоторые данные на основе контрольной суммы (ключ), то git возвращает ошибку, если ее не обнаружено (если она каким-то образом повреждена).

По существу, да. Предположим, что исходные правильные контрольные суммы данных до 1234. git хранит эту контрольную сумму и просматривает данные по этой контрольной сумме. (Так работает его "контент-адресная" вещь: обычно начинается с, например, имени ветки типа master, которое сопоставляется идентификатору фиксации, например 56789ab.... Это сопоставление хранится в git "refs", которые более уязвимы, чем остальные данные, но пусть на данный момент допустим, что эта часть остается неповрежденной.)

Git затем извлекает фиксацию по идентификатору и сравнивает контрольную сумму содержимого с идентификатором. Это должно совпадать, или содержимое фиксации повреждено. Предполагая, что содержимое является допустимым, они содержат (одиночный) идентификатор дерева (плюс информация о фиксации: кто его создал, когда его родители и т.д.).

Git затем извлекает содержимое дерева по идентификатору и сравнивает контрольную сумму содержимого с идентификатором. Это должно совпадать, или содержимое дерева повреждено. Предполагая, что содержимое является допустимым, они содержат ряд кортежей, дающих режимы, имена и идентификаторы файлов. Для каждой линии режим различает дополнительные деревья или простые файлы ( "blobs" ). Имя - это имя поддерева или файла, а идентификатор - контрольная сумма содержимого.

Git затем извлекает содержимое поддерева или blob по идентификатору и сравнивает контрольную сумму. Это должно совпадать или содержимое повреждено. Предполагая, что содержимое является допустимым, поддерево обрабатывается рекурсивно, как и раньше, и файл является правильным (не скомпрометирован).

Обратите внимание, что по пути любая пойманная ошибка просто говорит вам, что что-то пошло не так, но это не исправляет проблему; для этого вам нужна резервная копия (например, другая копия репозитория). Если сбой происходит довольно далеко по всему процессу, он очищает данные, которые являются коррумпированными, поскольку контрольные суммы действительны достаточно долго, чтобы найти фиксацию и дерево и, возможно, несколько поддеревьев до сбоя.

Если ссылки повреждены, их трудно восстановить. Тем не менее, git может перемещать каждый объект в базе данных и видеть, являются ли какие-либо "неподтвержденными". Такие объекты являются кандидатами на то, где должны указываться поврежденные ссылки. На самом деле, это на практике, как правило, бессмысленно сложно: вы просто переходите к той же резервной копии, которую вы будете использовать в случае поврежденного блоба.

Ответ 2

Но как это обеспечивает целостность данных? Если я найду некоторые данные на основе контрольной суммы (ключа), git вернет ошибку, если ее не обнаружит (если она каким-то образом повреждена).

Да.

И по данным, я имею в виду не только содержимое файла, но и всю историю (т.е. если родительская версия данной версии файла изменяется, все SHA1, связанные с изменением репозитория git. Данные все еще существуют, но другая часть его истории изменилась.

Я предполагаю, что данные могут портиться при использовании git - ошибок чтения диска и т.д.

Это один из примеров коррупции.
Но даже если данные остаются неповрежденными, целостность также противоречит любым изменениям (даже в метаданных, таких как имя автора или имя участника или дата: измените одно из них и SHA1 также изменится)

Это из-за диаграммы DAG данных, которые составляют git repo:

http://git-scm.com/book/en/v2/book/10-git-internals/images/data-model-3.png

(изображение из Git Внутренние - git Объекты")

Если вы изменяете любой из этих элементов, их родители тоже меняются.