Одно из ключевых различий между Git и большинством других систем управления версиями состоит в том, что другие, как правило, сохраняют фиксации в виде серии дельт - изменений между одной фиксацией и следующей. Это кажется логичным, так как это минимально возможное количество информации для хранения о фиксации. Но чем дольше сохраняется история фиксации, тем больше вычислений требуется для сравнения диапазонов версий.
В отличие от этого, Git хранит полный снимок всего проекта в каждой ревизии. Причина этого не в том, что размер репо резко возрастает с каждым фиксацией. Каждый файл в проекте хранится в виде файла в подкаталоге Git, названном для хеша его содержимого. Поэтому, если содержимое не изменилось, хэш не изменился, и фиксация просто указывает на тот же файл. И есть и другие оптимизации.
Все это имело смысл для меня, пока я не наткнулся на эту информацию о файлах пакетов, в которые Git периодически помещает данные для экономии места:
Чтобы сохранить это пространство, Gitиспользует пакетный файл. Это формате, где Git сохранит только часть, которая изменилась во второй файла с указателем на файл, который аналогично.
Разве это в основном не возвращается к хранению дельт? Если нет, то как оно отличается? Как это избежать, подвергая Git тем же проблемам, что и другие системы управления версиями?
Например, Subversion использует дельта, а откат 50 версий означает отмену 50 разностей, тогда как Git вы можете просто захватить соответствующий снимок. Если Git также не хранит 50 diff в файлах packfiles... есть ли какой-то механизм, который говорит "после небольшого количества дельт, мы будем хранить весь новый снимок", чтобы мы не накапливали слишком большой набор изменений? Как еще Git избежать недостатков дельт?