Ответ 1
Git включает для каждого коммита полную копию всех файлов, за исключением того, что для контента, уже присутствующего в репозитории Git, снимок будет просто указывать на указанный контент, а не дублировать его.
Это также означает, что несколько файлов с одинаковым содержимым хранятся только один раз.
Таким образом, снимок - это в основном коммит, ссылающийся на содержимое структуры каталогов.
Некоторые хорошие ссылки:
Вы говорите Git, что хотите сохранить снимок вашего проекта с помощью команды git commit, и он в основном записывает манифест того, как все файлы в вашем проекте выглядят в этот момент.
Лабораторная работа 12 иллюстрирует, как получить предыдущие снимки
Книга Progit содержит более полное описание снимка:
Основное различие между Git и любой другой VCS (включая Subversion и друзей) заключается в том, как Git думает о своих данных.
Концептуально большинство других систем хранят информацию в виде списка изменений на основе файлов. Эти системы (CVS, Subversion, Perforce, Bazaar и т.д.) Воспринимают информацию, которую они хранят, как набор файлов и изменения, вносимые в каждый файл с течением времени.
Git не думает и не хранит свои данные таким образом. Вместо этого Git думает о своих данных больше как набор снимков мини файловой системы.
Каждый раз, когда вы фиксируете или сохраняете состояние вашего проекта в Git, он в основном делает снимок того, как все ваши файлы выглядят в данный момент, и сохраняет ссылку на этот снимок.
Чтобы быть эффективными, если файлы не изменились, Git не сохраняет файл снова - просто ссылка на предыдущий идентичный файл, который он уже сохранил.
Git думает о своих данных, как показано ниже:
Это важное различие между Git и почти всеми другими VCS. Это заставляет Git пересматривать практически все аспекты контроля версий, которые большинство других систем скопировали из предыдущего поколения. Это делает Git больше похожим на мини файловую систему с несколькими невероятно мощными инструментами, построенными на ее основе, а не просто на VCS.
Ян Худек добавляет этот важный комментарий:
Хотя это верно и важно на концептуальном уровне, это НЕ верно на уровне хранилища.
Git использует дельты для хранения.
Не только это, но это более эффективно в этом, чем любая другая система. Поскольку он не хранит историю для каждого файла, когда он хочет выполнить дельта-сжатие, он берет каждый BLOB-объект, выбирает некоторые BLOB-объекты, которые могут быть похожими (используя эвристику, которая включает в себя самое близкое приближение предыдущей версии и некоторые другие), пытается генерировать дельты и выбирает самые маленькие. Таким образом, он может (часто зависит от эвристики) использовать преимущества других похожих файлов или более старых версий, которые более похожи на предыдущие. Параметр "окно пакета" позволяет торговать производительность для качества дельта-сжатия. Значение по умолчанию (10) обычно дает приличные результаты, но когда пространство ограничено или для ускорения передачи по сети,git gc --aggressive
использует значение 250, что делает его работу очень медленной, но обеспечивает дополнительное сжатие для данных истории.