Чего не хватает
Если у вас есть какие-либо теги, вам может потребоваться повторить ветку фильтра (начать с хорошей копии репозитория) и включить:
--tag-name-filter cat
в параметрах git filter-branch
.
Если в пакетах есть файлы keep
, они могут помешать удалению крупных объектов.(Если у вас есть действительно , вы, вероятно, знаете об этом.)
Обсуждение
Согласно выводу git выше,можно ли предположить, что файл, затронутый командой git, теперь УДАЛЕН из истории?
Точнее сказать, что существует новая история, в которой файл никогда не был добавлен , который присутствует в дополнение к существующей истории, в которой был добавлен файл .Каждая ссылка was rewritten
указывает на коммит в конце новой истории .Каждый is unchanged
указывает на коммит на кончике существующей неизмененной истории, что нормально, потому что в этой существующей неизмененной истории никогда не было файла.Например, представьте следующую сильно упрощенную диаграмму (всего с двумя ветвями):
A--B--C <-- master
\
D--E <-- Kunden
, где файлы ZeusSRC_Hardware_RPi_image_Raspberry
и Pi_außen_20.05.2019.zip
существуют в коммите D
.Итак, git filter-branch
извлеченный коммит D
, удалил два файла и сделал новый коммит, который мы назовем D'
, у которого больше нет файлов:
D'-E'
/
A--B--C <-- master
\
D--E <-- Kunden
Эти два файла могут или не могут бытьсуществует и в E
, но создание нового коммита D'
означает, что Git должен также создать новый E'
, и, конечно, новый E'
также удалит их, если они существовали в E
.
Теперь, когда новая история построена, Git должен отбросить существующий refs/heads/Kunden
и поместить в refs/heads/Kunden
(ветвь Кундена), указывающую на коммит E'
.С существующим refs/heads/master
все в порядке, поэтому его можно оставить в покое:
D'-E' <-- Kunden
/
A--B--C <-- master
\
D--E [original Kunden]
Имя refs/original/refs/heads/Kunden
, которое оставляет git filter-branch
, сохраняет фиксацию E
, но также делают различные менее видимые записи reflog.Первые из них - refs/original/*
имена - вот что это такое:
git for-each-ref --format="%(refname)" refs/original/ | xargs -n1 --no-run-if-empty git update-ref -d
, поскольку оно удалит каждое такое имя.
This:
git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc
предназначался для того, чтобы позаботиться о втором - reflogs, а также включить последний шаг git gc
.Рекомендация в документации git filter-branch
использует вместо этого две отдельные команды:
git reflog expire --expire=now --all
git gc --prune=now
От руки, я бы ожидал, что git gc
с элементами конфигурации будут работать, но если этонет, см. документацию ветки фильтра.
После того, как все ссылки на коммит E
исчезнут, и при условии, что нет ссылок на коммит D
, git gc
отбросит объекты D
и E
.Если эти объекты были упакованы, Git создаст новый файл пакета, в котором они отсутствуют, и превратит их в свободные объекты.При удалении незакрепленных объектов они будут отброшены после задержки удаления объекта, а старый файл пакета будет собираться мусором, если он не будет сохранен с файлом сохранения пакета.
Предположим, у вас есть тег имя , например v2.1
.Предположим далее, что имя тега указывает на фиксацию D
:
D'-E' <-- Kunden
/
A--B--C <-- master
\
D--E
.
...... <-- tag: v2.1
Поскольку refs/tags/v2.1
было не переписано, тег v2.1
продолжает сохранять коммит D
, который продолжаетсясохранить большой файл.Когда вы запускали ваш git filter-branch
, он создавал отображение, в котором учитывался тот факт, что новый коммит D'
был правильной заменой D
.Если у вас все еще есть отображение, вы можете использовать его для принудительного перемещения тега v2.1
, чтобы он указывал на фиксацию D'
.К сожалению, когда git filter-branch
заканчивается, он удаляет сопоставление, думая, что с ним все сделано, после выполнения всех операций «перезаписи» для различных имен.
(Примечание: естьgit rm origin
не требуется. Как вы можете видеть выше, ряд имен для удаленного отслеживания были переписаны, включая, например, refs/remotes/origin/Kunden
. Это означает означает, что вы не сможете обновитьдругой репозиторий Git на origin
без использования git push -f
, и если вы не обновите его, git fetch
вернет большие файлы.)
Последнее, это:
Ref 'refs/stash' was rewritten
означает, что ваш сохраненный тайник, вероятно, поврежден и больше не может быть применен.(Фильтр-ветвь не осознает, что тайники намеренно немного странны, и рассматривает их как обычные слияния, а иногда и нарушает их.)