Как git хранит файлы? - PullRequest
       4

Как git хранит файлы?

192 голосов
/ 20 ноября 2011

Я только начал изучать git и для этого начал читать Книгу сообщества Git , и в этой книге говорится, что SVN и CVS хранят разницу между файлами, а что git хранит снимок всехфайлы.

Но я так и не понял, что они имеют в виду под снимком.Действительно ли git делает копию всех файлов в каждом коммите, потому что это то, что я понял из их объяснения.

PS: Если у кого-нибудь есть лучший источник для изучения git, я был бы признателен.

Ответы [ 2 ]

235 голосов
/ 20 ноября 2011

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

Таким образом, моментальный снимок - это в основном коммит, ссылающийся на content структуры каталогов.

Вот некоторые полезные ссылки::

Вы говорите Git, что хотите сохранить снимок вашего проекта скоманда git commit и она в основном записывает манифест того, как все файлы вашего проекта выглядят в этот момент

Лабораторная работа 12 иллюстрирует, как получить предыдущие снимки


Книга Progit имеет более всеобъемлющийописание снимка:

Основное различие между Git и любыми другими VCS (включая Subversion и друзей) заключается в том, как Git думает о своих данных.
Концептуально, большинство других систем хранят информацию каксписок файловых изменений.Эти системы (CVS, Subversion, Perforce, Bazaar и т. Д.) Воспринимают информацию, которую они хранят, как набор файлов и изменения, внесенные в каждый файл с течением времени

delta-based VCS

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

snapshot-based VCS

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


Ян Худек добавляет это важный комментарий :

Хотя это верно и важно для концептуального уровня, на уровне хранения это НЕ верно.
Git использует дельты для хранения .
Не только это, но и более эффективно, чем в любой другой системе.Поскольку он не хранит историю для каждого файла, , когда он хочет выполнить дельта-сжатие , он берет каждый BLOB-объект, выбирает некоторые BLOB-объекты, которые могут быть похожими (используя эвристику, которая включает в себя наиболее близкое приближение предыдущей версии инекоторые другие), пытается генерировать дельты и выбирает самые маленькие.Таким образом, он может (часто зависит от эвристики) использовать преимущества других похожих файлов или более старых версий, которые более похожи на предыдущие.Параметр «окно пакета» позволяет торговать производительность для качества дельта-сжатия.Значение по умолчанию (10) обычно дает приличные результаты, но когда пространство ограничено или для ускорения передачи по сети, git gc --aggressive использует значение 250, что делает его работу очень медленной, но обеспечивает дополнительное сжатие для данных истории.

40 голосов
/ 20 ноября 2011

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

Но это также означает, что при изменении небольшой частифайл и фиксация, другая копия файла сохраняется.Git решает эту проблему с помощью файлов пакета.Время от времени все «свободные» файлы (на самом деле, не только файлы, но и объекты, содержащие информацию о коммитах и ​​каталогах) из репозитория собираются и сжимаются в пакетный файл.Файл пакета сжимается с помощью zlib.И подобные файлы также дельта-сжаты.

Этот же формат также используется при извлечении или выталкивании (по крайней мере, с некоторыми протоколами), поэтому эти файлы не нужно повторно сжимать снова.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...