Как очистить репозиторий git с фиксацией, которой нет в рабочем дереве

Я очистил репозиторий Git (облако Bitbucket) с помощью bfg, но последний коммит остался неочищенным (как написано в документации bfg: по умолчанию BFG не изменяет содержимое вашего последнего коммита в ветке master (или «HEAD»). , даже если он очистит все коммиты перед ним.).

Однако я этого не увидел и хотел запустить git gc в Bitbucket.
Для этого я сделал "git reset --hard HEAD" и откатился на него потом "git push --force".
Но размер репозитория увеличился?!

Теперь у меня в репозитории остался этот коммит со старой историей, и bfg не может его почистить, что мне делать?
Как его удалить, раз он уже не привязан к рабочему дереву?


person ConorHolt    schedule 26.10.2019    source источник


Ответы (3)


Вы также можете указать BFG изменить последнюю фиксацию с помощью флага --no-blob-protection. *(Это из документации BFG-Repo-Cleander).

В качестве альтернативы вы можете создать новую фиксацию, которая удалит плохой файл, а затем запустить BFG в обычном режиме.

person David Sugar    schedule 26.10.2019
comment
Пробовал так сделать, но коммита уже нет в рабочем дереве и бфг его не видит - person ConorHolt; 28.10.2019

Я написал в поддержку битбакета, они запустили скрипт "git gc" на сервере, и старая история была очищена.

person ConorHolt    schedule 28.10.2019
comment
Вы должны иметь возможность запускать git gc на стороне BitBucket (без необходимости связываться с ними). См. мой отредактированный ответ. - person VonC; 28.10.2019
comment
Я знаю, я так делал, мне не помогло - person ConorHolt; 29.10.2019
comment
Служба поддержки Bitbucket могла бы ответить на вопрос, почему их собственный процесс не вызвал ошибку git gc. - person VonC; 29.10.2019

Попробуйте еще раз, на этот раз используя newren/git-filter-repo, который заменит BFG и git filter-branch

Как указано в его документации:

[есть] дополнительные шаги для удаления других тегов и выполнения другого gc по-прежнему требуются для очистки старых объектов и предотвращения смешивания новой и старой истории перед отправкой куда-либо

git filter-repo не сбивает пользователей с толку (и предотвращает случайное повторное размещение старых материалов) из-за смешивания старого и переписанного репозитория.


Примечание: на стороне сервера (то есть там, куда вы отправляете данные) необходимо запускать git gc, что выполняется регулярно, но не сразу.
Это кейс для GitHub, а также BitBucket.

См. документацию Atlassian "Как выполнить ручную сборку мусора в репозитории"

Bitbucket реализует собственную логику сборки мусора, больше не полагаясь на git gc (это достигается установкой [gc] auto = 0 во всех репозиториях).
Когда создается вилка, pruneexpire=never добавляется в конфигурацию git и это удаляется, когда удаляется последняя вилка.

Как упоминалось здесь:

BitBucket запустит git gc в ответ на выполнение git reset --hard HEAD~1 (которое отменяет последний коммит), за которым следует git push -f.

Итак, в вашем случае:

git commit --allow-empty -m "empty commit"
git push

git reflog expire --expire-unreachable="30m" --all
git prune --expire="30m" -v
git gc --prune="30m"
git reset --hard HEAD~1
git push -f

И git gc нужно сделать на стороне BitBucket!

person VonC    schedule 26.10.2019