Каковы преимущества адресации на основе содержимого в Git?

#git #sha

#git #sha

Вопрос:

Вопрос:

Git использует систему адресации файлов на основе содержимого (то есть использует большие двоичные объекты и хэши деревьев в качестве «имен файлов»). Мне было интересно, каковы преимущества такой системы адресации?

Я ясно вижу некоторые преимущества, но они незначительны:

  1. Если кто-то изменит какой-либо файл в репозитории git, это приведет к разрыву всех коммитов, которые указывают на него. Таким образом, вы наверняка будете знать, что произошло что-то плохое. Но действительно ли это так полезно?
  2. Использование хэша для файла отделяет реальное имя файла от его содержимого, и, таким образом, вы можете «дешево» переименовать файл…

Я чувствую, что истинная причина использования sha для адресации файлов совсем другая. Кто-нибудь может объяснить?

Постскриптум Разъяснение. Вопрос в ТОМ, ПОЧЕМУ Git использует хэши для адресации файлов, а не КАК он это делает. Я знаю, КАК это сделать, мне нужно знать, ПОЧЕМУ.

P.P.S. Есть статья о принципах Git и о том, почему Git выглядит так странно (потому что его следует использовать на компьютере, где нет другого программного обеспечения, кроме основной ОС и текстового редактора), но все же в этой статье упоминается только это, ПОЧЕМУ:

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

Хорошо, вот ПОЧЕМУ я понимаю. Любой другой, ЗАЧЕМ использовать файловую систему с адресом содержимого?

Комментарии:

1. Перечисленные вами преимущества уже кажутся мне достаточными. Действительно ли быстрые, абсолютные проверки целостности содержимого и устранение избыточности в content tracker не кажутся достаточно желательными качествами?

2. Ну, я подумал, может быть, есть и другие, более важные преимущества.

3. «Если кто-то изменит какой-либо файл в репозитории git, это приведет к разрыву всех коммитов, которые указывают на него». Коммиты не указывают на файлы.

4. да, я знаю, но коммит будет «сломан», поскольку он указывает на деревья, которые указывают на большие двоичные объекты и т.д.

5. Стоит отметить: другие системы контроля версий используют другие методы. Они работают. Это доказывает, что способ , которым Git выполняет управление версиями, не единственный способ, которым можно управлять версиями. В конечном счете, ответ на вопрос «почему» прост: потому что Линус Торвальдс написал это именно так . Есть и другие способы, которые работают. Если они вам нравятся, рассмотрите возможность использования одного из этих других VCSE (Mercurial, p4, bazaar, darcs и т. Д.).

Ответ №1:

Одна из наиболее распространенных вещей, которые git должен сделать, это сравнить две версии проекта. Поскольку хранилище объектов (коммиты, деревья и большие двоичные объекты) могут быть адресованы содержимому, это можно сделать очень быстро, сравнив «имена файлов».

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

Комментарии:

1. Итак, как только вы что-то фиксируете, Git пересчитывает все хэши для всех файлов в рабочем каталоге и ищет совпадение в своей «базе данных»? Верно? Для меня это выглядит пустой тратой времени, но, да, как вы можете отслеживать, какие файлы изменились и как они изменились…. ОК. Понял. Итак, вкратце: Git использует хэш для файлов как метод отслеживания изменений. Является ли это ОСНОВНОЙ причиной использования хэшей? Есть ли другие веские причины?

2. Нет, git не пересчитывает все хэши для всех файлов в рабочем каталоге. Он полагается на fstat, чтобы узнать, был ли рабочий файл потенциально изменен (что является надежным, если только кто-то намеренно не пытается скрыть изменение), и его можно настроить так, чтобы пропустить эту проверку также для подкаталогов, где даже это было бы пустой тратой времени. Кроме того, это актуально, когда вы add — не когда вы commit , что на самом деле не связано с рабочим каталогом. Процесс add ввода вычисляет хэш любого потенциально измененного объекта и сохраняет его в индексе по мере необходимости

3. Как сказал @MarkAdelsberger, Git не нужно каждый раз повторно хэшировать каждый файл. Помимо того факта, что git commit он просто считывает то, что находится в индексе Git (включая список имен файлов и идентификаторов больших двоичных объектов), git add он пропускает много вещей через аспект кэша индекса Git, в котором хранятся lstat данные на уровне ОС. (Это lstat не fstat потому, что в Git файлы не открыты постоянно.) Кэш также может взаимодействовать с мониторингом файловой системы, если ваша ОС предлагает это.

Ответ №2:

Этот хэш является уникальным идентификатором объекта. Вы могли бы сделать то же самое с большими двоичными объектами, которые вы храните в БД — вычислите хэш и сделайте его идентификатором. Который имеет такие преимущества, как:

  1. Дедупликация. Если у вас один и тот же большой двоичный объект (один и тот же файл в Git) — вы не будете дублировать данные — они будут сохранены один раз и на них будут ссылаться из разных мест. Это означает, что:
    • Вы можете скопировать один и тот же файл или папку, и в Git «database» не будет никаких дубликатов, только несколько ссылок на один и тот же большой двоичный объект. Таким образом, объем пространства для хранения / передачи сведен к минимуму.
    • При переименовании / перемещении файлов их содержимое больше не будет добавлено в Git с другим именем. Git сгенерирует тот же хэш и, таким образом, быстро распознает, что создавать новые объекты не нужно. Опять же — одни и те же объекты будут ссылаться из разных мест.
    • Если вы удалите файл одним коммитом, а затем снова добавите его в другой коммит, новые объекты все равно не будут созданы, поскольку старые все еще находятся в .git (на них ссылаются старые коммиты, поэтому они должны оставаться .git ).
  2. Кроме того, как вы можете быстро показать разницу между 2 коммит? Для Git это просто, поскольку папки — это просто объекты (деревья), которые ссылаются на большие двоичные объекты и другие папки, и эта информация также адресуется содержимому. Итак, если дерево (папка) теперь ссылается на другой большой двоичный объект / дерево (или их имена изменены) — идентификатор на основе хэша изменится. Таким образом, Git может сначала проверить хэши деревьев (папок), чтобы увидеть, отличается ли их содержимое и нужно ли Git заходить внутрь, чтобы проверить другие различия.
  3. Вам не нужно хранить дополнительную базу данных (метаинформацию) о том, какой суррогатный идентификатор ссылается на какие данные. Идентификатор может быть выведен из содержимого.

PS: хотя пункты 1-2 могут быть достигнуты и с помощью суррогатного идентификатора, вам просто нужно будет сохранить хэш вместе с этими идентификаторами. Поэтому перед сохранением нового файла вам нужно будет вычислить его хэш и найти суррогатный идентификатор по хэшу в базе данных. Менее удобно, но возможно.

Комментарии:

1. да, это понятно. итак. # 3 и # 4 — все веские причины для хэшей, а # 1 и # 2 кажутся побочным эффектом этих. Я имею в виду, что 1 и 2 не были основной причиной использования хэш-адресов

2. Я действительно не вижу # 2 здесь уместным. Переименования / перемещения просты во всех распространенных файловых системах * nix, и они не адресуются содержимому. Ключом к этому является то, что идентификатор файла (или BLOB ) для целей хранения является отдельной вещью от удобочитаемого пути / имени файла

3. @MarkAdelsberger, если вы попросите Git переименовать / переместить файлы, то да, это не проблема. Но если вы сделали это извне (с mv помощью) — Git не участвовал и не имеет информации о том, что произошло. Таким образом, идентификатор на основе хэша помогает выяснить, что этот объект уже существовал, и нам не нужно добавлять его снова.

4. В том, что вы только что сказали, есть пара неправильных представлений. Не имеет значения, указываете ли вы git переместить файл или переместить его извне; в любом случае, git записывает «файл удален по пути X; файл создан по пути Y». Более того, вы объединяете применение дедупликации со стороной «файл, созданный по пути Y», с легкостью самого переименования. Как я уже отмечал, системы, которые не адресуются содержимому, имеют точно такую же простоту переименования файлов.

5. @MarkAdelsberger, системам, которые не адресуются к содержимому (типичным файловым системам), предлагается перемещать / переименовывать файлы. Именно они выполняют действие . С другой стороны, Git имеет «состояние до» и «состояние после». Поэтому во git add время ит-процесса необходимо понимать, что «состояние после» на самом деле такое же, как и раньше, поскольку идентификатор уже существует, следовательно, новый большой двоичный объект не создается. вы объединяете применение дедупликации… с легкостью самого переименования — Да. Я просто привожу примеры того, когда происходит удаление дублирования. Итак, пункт № 2 является скорее подпунктом к пункту № 1. Возможно, мне следует переструктурировать эту часть..