Это распространенное заблуждение, что git хранит различия.Он на самом деле хранит полное содержимое каждой версии *.На самом деле, вся модель git построена вокруг гарантированного безупречного извлечения исходного кода, чего просто не могут добиться VCS на основе diff.
Возможно, вы либо получили два коммита сдвоичные файлы, или вы считаете как копию в базе данных, так и копию в рабочем каталоге.
Для ответа на ваш основной вопрос.
Git хранит данные как набор объектов, которые ссылаются надруг с другом.(См. Деревья Меркле ). Поскольку деревья и история построены из объектов, которые ссылаются на другие объекты, очень трудно действительно удалить общие данные из репозитория git.
"Переписывание истории"это даже немного неправильно, поскольку git никогда не переписывает историю, он просто возвращается и создает новую историю, а затем указывает на эту новую историю.Старые вещи могут зависать месяцами перед сборкой мусора.Как только вы начинаете делиться этим, в логической модели git ваша переписанная история - это просто еще одна ветвь в другом экземпляре репо.
Обычно ветки перемещают кодовую базу вперед и могут быть объединены для получения этой истории.все вместе.Если у вас есть ветвь функций с именем feature1
и слияние ее с веткой master
, это не только код, который становится частью мастера, все коммиты на feature1
также становятся частью мастера.Когда каждая ветвь представляет собой отдельный фрагмент кода, это не проблема.
Это становится проблемой, когда вы пытаетесь переписать историю.Допустим, вы делаете то, что предлагаете, и удаляете код из истории, используя фильтр-ветвь (хотя перебазировка будет проще и, вероятно, безопаснее, это довольно недавно).Каждый член вашей команды удаляет свою локальную копию этой ветки и проверяет новую.Все замечательно, за исключением того, что вы работали над featureX и уже слили ветку master в нее после того, как произошла ошибка, поэтому старый master является частью вашей ветви featureX.Выполнение diff между featureX
и master
покажет те же результаты, что и diff между featureX
и старым мастером, но все эти коммиты все еще являются частью featureX
.В мозгу git, featureX
разветвлялся в тот момент, когда были добавлены большие файлы, и когда вы объединяете его в мастер, featureX
возвращает все обратно с ним.
Так что это опасность, если даже одинУ человека, находящегося где-то в любой из его ветвей, все еще есть копия старого коммита в истории, у вас останется не только файлы, от которых вы пытаетесь избавиться, но и целая вторая версия истории, чтобыразберитесь также.
Если вы должны удалить его, это можно сделать, но вам нужно будет очень тщательно скоординировать процесс, чтобы убедиться, что каждый экземпляр хранилища был очищен.С очень небольшой командой это не ужасно, но чем больше и более распределена ваша команда, тем сложнее она становится.
* Она делает некоторые умные вещи с дельта-сжатием, когда упаковывает объекты для хранения,но всегда таким образом, чтобы гарантировать немного идеальную реконструкцию.Git обнаружит даже один бит неуместным во всей истории как сломанный репо.