Ответ от ученика по коду в основном правильный, но немного уточним:
Невозможно изменить коммит. filter-branch
(или любой механизм переписывания истории) создает новые коммиты, которые «похожи» на существующие коммиты, но с изменениями, которые вы запрашиваете. (например, ваши новые коммиты не содержат большого файла, но в остальном они выглядят как ваши старые коммиты)
Это имеет два важных следствия.
Во-первых, после того, как вы переписали историю ветки, любому, у кого есть копия этой ветки, нужно будет выполнить некоторые шаги восстановления. Вы можете узнать об этом в документации git rebase
(в разделе «восстановление из исходной версии»). Если они делают не то, что нужно для восстановления, это отменит переписывание истории (поместив большой файл обратно в историю), поэтому вам нужно, чтобы все сотрудничали при переписывании истории. По этой причине иногда переписывать историю нецелесообразно. Для больших переписываний (особенно тех, которые влияют на сложную историю, множественные ветви и т. Д.) Часто лучше организовать обрезку, при которой каждый отбрасывает свои существующие клоны, а затем повторно клонирует из переписанного репо.
(Нюанс в том, что любой инструмент или документация, которая зависит от идентификаторов фиксации, также нарушается при перезаписи истории.)
Во-вторых, это означает, что перезапись не приводит к немедленному удалению старых коммитов из репо. Это важно как в том случае, если вы пытаетесь освободить пространство от двоичного раздувания, так и в том случае, если вы пытаетесь устранить утечку конфиденциальной информации в историю репо. (В последнем случае почти всегда необходимо обращаться с информацией как скомпрометированной.)
Запуск git gc
может быть частью решения, но этого недостаточно. Это потому, что сразу после переписывания в вашем репо все еще есть ссылки на старые коммиты, поэтому gc
не видит их как мусор. Как минимум, вам нужно очистить флаги; могут быть и другие проблемы.
Есть способы сделать это, но обычно я обошёл проблему, просто сделав новый клон из переписанного репо. Этот клон не должен беспокоить копирование старой / удаленной истории. (Чтобы быть ясным - я не думаю, что есть какое-либо задокументированное требование, в котором говорится, что такой клон не может копировать историю несуществующей, но по моему опыту - по крайней мере, при использовании стандартной реализации git - это не ' т.) Затем вы можете уничтожить исходный репо и воссоздать его из полностью продезинфицированного клона.