Git не выбрасывает информацию самостоятельно *. Все предыдущие версии каждого файла всегда доступны для возврата, различий, проверок и так далее.
Целое дерево против отдельных файлов
Возможно, вы пытаетесь согласовать идею доступа к старой версии отдельного файла по сравнению с тем фактом, что модель истории Git сфокусирована на всем дереве. Управление версиями для всего дерева требует немного больше работы, чтобы увидеть (например) версию, foo.c
существовавшую десять foo.c
изменений назад по сравнению с десятью изменениями всего дерева назад:
# 10 foo.c-changes ago
git show $(git rev-list -n 10 --reverse HEAD -- foo.c | head -1):foo.c
# 10 whole-tree-changes ago
git show HEAD~10:foo.c
Преимущества древовидной ориентации, в основном возможность просматривать коммиты как единицу взаимозависимых изменений, внесенных в различные части всего дерева, в целом значительно перевешивают дополнительную типизацию (которая может быть уменьшена с помощью псевдонимов, сценариев и т. Д.) И время процессора копаться в прошлых коммитах.
Эффективность хранения
Когда в систему попадает новый объект (например, файл с ранее невидимым содержимым), он сохраняется с простым (zlib) сжатием как «свободный объект». Когда накапливается достаточное количество незакрепленных объектов (в зависимости от параметра gc.auto
конфигурации; или когда пользователь запускает git gc или одну из команд упаковки более низкого уровня), Git собирает много незакрепленных объектов в один «файл пакета».
Объекты в файле пакета могут храниться как простые сжатые данные (такие же, как незакрепленный объект, просто связанный с другими объектами), так и как сжатые дельты с некоторыми другими объектами. Дельты могут быть объединены в цепочку с настраиваемой глубиной ( pack.depth
) и могут создаваться для любого подходящего объекта ( pack.window
контролирует, насколько широко Git ищет лучшую дельта-базу; версию исторически несвязанного файла можно использовать в качестве базы, если это приведет к хорошая дельта компрессия). Широта, которую конфигурации глубины и размера окна дают механизму дельта-сжатия, часто приводят к лучшему дельта-сжатию, чем простое сжатие «diff» в стиле CVS «одна версия против следующей / предыдущей версии».
Именно это агрессивное дельта-сжатие (в сочетании с обычным сжатием zlib) часто позволяет Git-репозиторию (с полной историей и несжатым рабочим деревом) занимать меньше места, чем одна проверка SVN (с несжатым рабочим деревом и нетронутой копией).
См., Как Git хранит объекты и разделы Packfile в Git Community Book . Кроме того , мерзавец пачка объектов страницы руководства .
* Вы можете сказать Git выбросить коммиты «переписав историю» и с помощью таких команд, как git reset , но даже в этих случаях Git «зависает» на недавно отмененных коммитах на некоторое время, на тот случай, если вы решите, что они вам нужны. Смотрите git reflog и git prune .