Можно ли очистить файлы удаленного репо с неправильными фиксациями на GitHub?

Общие сведения. У меня возникла вложенная проблема для одного из наших репозиториев, удаленно размещенного в версии GitHub для предприятий, которую использует моя компания.

Я думаю, что самый простой способ справиться с этим, учитывая, сколько лет репозиторию, — это каким-то образом удалить старые жестко зафиксированные файлы, которые никогда не должны были быть зафиксированы в первую очередь, которые предположительно хранятся где-то либо напрямую, либо по ссылке. Хитрость в том, что я не хочу возиться с историей, если это может помочь, и я мало знаю о более продвинутых функциях git, поэтому трудно даже понять, какой правильный вопрос. просить.

Проблема: репозиторий занимает слишком много времени для извлечения/извлечения через Jenkins через подключаемый модуль GitSCM. Время ожидания истекает примерно через 10 минут. В этом репозитории есть тысячи коммитов и десятки тегов, которые нужно отслеживать, поэтому я не могу произвольно установить определенный коммит как хорошую точку для начала и обрезать остальные.

Мои выводы: Попытка сделать то, что, кажется, делает подключаемый модуль GitSCM, не приводит ни к каким проблемам или временным затратам. Тем не менее, он по-прежнему невероятно медленный, просто не более 10 минут, поэтому нам, вероятно, следует почистить это, даже если плагин вызывает усугубление проблем с производительностью.

Возможные оптимизации: я обнаружил, что несколько коммитов были добавлены в основном DLL. С тех пор эти библиотеки DLL были удалены с помощью новых коммитов. Однако размер репо по-прежнему составляет сотни мегабайт по сравнению с тем, что фактически используется локальной файловой системой. Прямо сейчас главная ветвь занимает около 4 МБ вне папки .git, что составляет около 300 МБ.

Цель: избавиться от как можно большей части этих 300 МБ, не раздражая людей потерей истории/тегов.

Я пробовал множество решений из возможных связанных проблем, но мне не удалось получить его, когда удаленное размещенное репо уменьшено до чего-то более близкого к фактическому размеру, используемому файловой системой. Некоторые из этих вопросов были,

Уменьшить размер репозитория git
Как удалить неиспользуемые объекты из репозитория git?
Почему git больше не уменьшает размер репозитория?

Попробовав решения этих вопросов, я в итоге только увеличил размер репо, а не уменьшил его, о чем, честно говоря, меня предупредили в одном из ответов на эти вопросы.

Учитывая предысторию этой проблемы, детали проблемы и ранее упомянутые вопросы, можно ли выполнить то, что я пытаюсь сделать в удаленном репозитории, и если да, то что конкретно я должен запустить или попросить наших администраторов GHE запустить если я лично не могу сделать обновление?

В итоге это привело к росту:

git reflog expire --all --expire=now
git gc --prune=now --aggressive
git filter-branch --index-filter "git rm --cached --ignore-unmatch *.dll" --prune-empty -- --all
git push origin master

Однако после выполнения первых двух команд размер папки .git уменьшился только на 40 МБ; далеко не то, на что я надеялся, поэтому я попробовал следующую команду в последовательности, которая при удаленном нажатии вызывала рост репо, а не его сжатие. Количество объектов увеличилось с 45 до 60 тысяч.


person kayleeFrye_onDeck    schedule 17.04.2018    source источник


Ответы (2)


Хитрость в том, что я не хочу связываться с историей, если это может помочь,

Но вы: git filter-branch или (проще в использовании) очиститель репо BFG перезапишет историю (SHA1) коммитов этого репозитория, заставив вас git push --force вернуть конечный результат обратно в удаленный репозиторий.
Это не имеет большого значения, учитывая, что репозиторий старый (т.е. активно не поддерживается больше), но все же необходимо учитывать.

Репо занимает слишком много времени, чтобы вытащить/извлечь его через Jenkins через плагин GitSCM.

Дженкинс здесь вообще не должен быть замешан: можно локально клонировать репо, почистить его и запихнуть обратно.
Плюс таймаут в Дженкинсе можно поднять.

В итоге это привело к росту:

Предполагается, что эти команды reflog/gc должны использоваться после ветки фильтра или BFG, а не до.

person VonC    schedule 17.04.2018
comment
Теперь это некоторые фантастические отзывы и идеи! Я попробую это первым делом, когда смогу, и приму это как ответ, если все пойдет хорошо, или отвечу обновлениями в натуральной форме :) - person kayleeFrye_onDeck; 17.04.2018
comment
VonC, я попробовал последовательность из вопроса, но с запуском этого ниже. На этот раз папка .git уменьшилась в размере всего на 1 МБ, а объекты выросли до 59 КБ. Любая идея, что я могу делать неправильно? git filter-branch --index-filter "git rm --cached --ignore-unmatch *.dll" --prune-empty -- --all ; git reflog expire --all --expire=now ; git gc --prune=now --aggressive ; git push --force origin master - person kayleeFrye_onDeck; 18.04.2018
comment
@kayleeFrye_onDeck Полная последовательность: stackoverflow.com/a/47194749/6309 - person VonC; 18.04.2018
comment
VonC -- это дало странный результат. При запуске git-filter перед командами в связанном ответе он успешно уменьшил размер папки .git. Выполнив git push --force origin master, я повторно клонировал репозиторий, и он фактически снова увеличился в размере за отметку в 300 МБ. Итак, это работает локально, но не удаленно; есть идеи, что мне не хватает? Может быть, я вас неправильно понял, и мне нужно попросить наших администраторов GHE запустить эти команды непосредственно для репозитория из фактического экземпляра хостинга GitHub? - person kayleeFrye_onDeck; 18.04.2018
comment
Кстати, этого я не делал: rm -Rf .git/refs/original так как нигде этого не видел; есть ли обобщенный эквивалент, который я должен выполнять/высматривать? Мой каталог .git\refs содержит только подкаталоги с именами heads ; remotes ; tags - person kayleeFrye_onDeck; 18.04.2018

Я не собираюсь принимать свой собственный ответ. VonC проделал замечательную задачу, пытаясь массировать ответ в комментариях, чтобы удовлетворить мои очень специфические требования, которые могут не сдерживать других людей с аналогичными проблемами - кроме того, VonC упомянул об использовании BFG, что в конечном итоге разблокировало меня. Было бы неплохо заставить это работать только с git, но поскольку BFG абсолютно бесплатен (а также намного быстрее, чем git filter-branch), я не могу игнорировать его как альтернативу решению проблем с git.

Чтобы разблокировать наши удаленные сборки, уменьшив размер репо в папке .git, я использовал бесплатный инструмент BFG Repo Cleaner и в точности следовал его инструкциям. Он уменьшил размер папки .git с исходных 300 МБ до 80 МБ. Учитывая, что в этом репозитории было более 7 тысяч коммитов, я не собираюсь жаловаться на то, что папка .git все еще велика. Эта операция определенно значительно ускорила процесс клонирования репозитория.

Как

Полное раскрытие: некоторые из этих шагов напрямую скопированы из документации BFG Repo Cleaner, которая связана с шагом №2. Также предполагается, что вы используете Windows, поэтому обновите синтаксис оболочки по мере необходимости.

  1. Установите Java, если у вас его еще нет
  2. Загрузите бесплатный инструмент BFG Repo Cleaner с их сайта здесь, который также их страница документации
  3. Если вы не хотите выполнять ту же операцию, что и я, когда я удаляю все типы файлов .DLL, ознакомьтесь с краткой документацией BFG, чтобы узнать, что еще доступно.
  4. Откройте командную консоль и выполните неглубокое клонирование, используя --mirror для вашего репозитория, например:
    git clone --mirror https://github.com/some-big-repo.git
  5. Если java.exe нет в вашем пути, либо временно добавьте этот каталог в PATH с Set PATH=%PATH%;C:\PathToJavaBin, либо вызовите его напрямую и обязательно обновите эту команду имени файла JAR, чтобы приведенная ниже команда соответствовала тому, что находится в вашей файловой системе, как таковой:
    C:\PathToJavaBin\java.exe -jar C:\PathToBFGJar\bfg.jar --delete-files *.dll some-big-repo.git
  6. беги cd some-big-repo.git
  7. беги git reflog expire --expire=now --all
  8. беги git gc --prune=now --aggressive
  9. беги git push

И это было :)

person kayleeFrye_onDeck    schedule 17.04.2018
comment
Я подозреваю, что последний толчок - это push --force, но в остальном я согласен (и упомянул BFG в своем собственном ответе). +1 - person VonC; 18.04.2018