Конфіденційні дані або надмірне споживання пам’яті: є вагомі причини змінити історію Git. У цій публікації блогу я пояснив, як очистити файли з історії Git за допомогою BFG . Слабкою стороною BFG є відсутність підтримки прямих шляхів , тому ви не можете спеціально видалити файли чи папки у вкладених папках з історії. З огляду на це, настав час поглянути на альтернативні рішення.
На додаток до офіційно не рекомендованої гілки git filter , git-filter-repo є одним із інструментів для очищення історії. Після короткої інсталяції ми спочатку аналізуємо репозиторій і знаходимо, наприклад, найбільші папки в історії:
git filter-repo --analyze
Ну бути в папці .git/filter-repo/analysis
генерував усі види файлів TXT:
directories-all-sizes.txt
extensions-all-sizes.txt
path-all-sizes.txt
- ...
Файл вартий directories-all-sizes.txt
подивіться уважніше:
=== All directories by reverse size ===
Format: unpacked size, packed size, date deleted, directory name
4624417043 3796607988 <present> <toplevel>
4475940396 3778033787 <present> wp-content
4060236681 3694449320 <present> wp-content/uploads
305163809 70576241 <present> wp-content/plugins
123818107 15442735 <present> wp-includes
...
Часто трапляється так, що ви довго ігнорували та видаляли з HEAD дані в історії (наприклад, медіа-папку WordPress wp-content/uploads/
або випадково штовхнутий node_modules
- або vendor
-Біндер).
Загалом рекомендую git-filter-repo
після очищення, переміщення до нового, порожнього сховища. Тут перераховано багато причин, чому це має сенс і дозволяє уникнути багатьох проблем. Тим не менш, може трапитися так, що ви захочете перейти до того самого репозиторію, і це також можливо за допомогою кількох підказок.
Важливо, основні платформи для розміщення коду GitHub і GitLab рекомендувати різні підходи, деякі з яких відрізняються один від одного. Наприклад, на GitHub видаляємо wp-content/uploads/
за допомогою наступних кроків git-filter-repo
з історії:
mkdir tmp-repo
cd tmp-repo
git clone git@github.com:foo/bar.git .
cp .git/config /tmp/config-backup
git filter-repo --invert-paths --path wp-content/uploads/
# option 1: same repo
mv /tmp/config-backup .git/config
git push origin --force --all
# option 2: new repo
git remote add origin git@github.com:foo/bar-new.git
git push origin --force --all
cd ..
rm -rf tmp-repo
Тепер ми також можемо перевірити розмір віддалено (зміна розміру через API та в інтерфейсі користувача може тривати до 24 годин). Для цього відкрийте налаштування репозиторію (якщо репозиторій належить організації, ви повинні спочатку додати власний обліковий запис до організації). Тепер бачимо розмір:
У GitLab процедура дещо відрізняється:
mkdir tmp-repo
cd tmp-repo
# option 1: same repo
# Settings > General > Advanced > Export project > download tar.gz file into tmp-repo
tar xzf 20*.tar.gz
git clone --bare --mirror project.bundle
cd project.git
git filter-repo --invert-paths --path wp-content/uploads/
cp ./filter-repo/commit-map /tmp/commit-map-1
# copying the commit-map has to be done after every single command from git filter-repo
# you need the commit-map files later
git remote remove origin
git remote add origin git@gitlab.com:foo/bar.git
# Settings > Repository > Protected branches/Protected branches >
# enable "Allowed to force push to main/master"
git push origin --force 'refs/heads/*'
git push origin --force 'refs/tags/*'
git push origin --force 'refs/replace/*'
# Settings > Repository > Protected branches/Protected branches >
# disable "Allowed to force push to main/master"
date
# wait 30 minutes (😱)
date
# Settings > Repository > upload /tmp/commit-map-X
# option 2: new repo
git clone git@gitlab.com:foo/bar.git .
git filter-repo --invert-paths --path wp-content/uploads/
git remote add origin git@gitlab.com:foo/bar-new.git
# Settings > Repository > Protected branches/Protected branches >
# enable "Allowed to force push to main/master"
git push origin --force --all
# Settings > Repository > Protected branches/Protected branches >
# disable "Allowed to force push to main/master"
cd ..
rm -rf tmp-repo
Після чергового очікування ~5 хвилин ми можемо піти під воду Settings > Usage Quotas
переглянути простір для зберігання:
Після видалення важливо, щоб усі залучені розробники були залучені до останніх кроків: якщо користувач зараз виконає звичайний push із власною локальною копією, це призведе до міграції великих файлів назад до центрального сховища. Тому рекомендовано наступні 3 варіанти:
- "свіжий клон бідняка"
rm -rf .git && git clone xxx temp && mv temp/.git ./.git && rm -rf temp
- Для змінених файлів (залежно від програми):
git checkout -- .
або.git add -A . && git commit -m "Push obscure file changes." && git push
- "починати з нуля"
rm -rf repo && git clone xxx .
- "потворне витягування з перебазуванням"
git pull -r
- Тут у вас все ще є неочищена історія, але в більшості випадків ви більше не випадково перезаписуєте віддалений репозиторій великим локальним варіантом
У рамках поточних квот (особливо через нові обмеження GitLab ) завжди варто перевіряти розмір історії ваших репозиторіїв і очищати їх, якщо необхідно:
GitHub безкоштовно | GitLab безкоштовно | |
Максимальний розмір файлу | 100 МБ | ∞ |
Обмеження максимального розміру репо | 5000 Мб | ∞ |
Обмеження максимальної кількості репо | ∞ | ∞ |
Максимальний загальний розмір | ∞ | 5000 Мб |
Нарешті, також варто поглянути на безкоштовний варіант, який розміщується самостійно Гітея кидати. З невеликими зусиллями ви можете на a дуже тонкий сервер саморозміщений екземпляр Git (GUI per SSL забезпечені, Резервне копіювання включено, контроль над потужний API) хост, які також чудові налаштувати а також кращий з точки зору захисту даних. Тут, до речі, теж можна використовувати git-filter-repo
Просто оптимізуйте сховища:
mkdir tmp-repo
cd tmp-repo
git clone git@git.tld.com:foo/bar.git .
cp .git/config /tmp/config-backup
git filter-repo --invert-paths --path wp-content/uploads/
# option 1: same repo
mv /tmp/config-backup .git/config
git push origin --mirror
# login on the remote command line and run in the repo-folder
sudo -u git git reflog expire --expire=now --all
sudo -u git git gc --aggressive --prune=now
# if you face memory limit issues, modify the git configuration
sudo -u git git config --global pack.windowMemory "100m"
sudo -u git git config --global pack.packSizeLimit "100m"
sudo -u git git config --global pack.threads "1"
# if in web ui the size does not change, make a slight
# modification to a file and push again normally
# option 2: new repo
git remote add origin git@git.tld.com:foo/bar-new.git
git push origin --force --all
cd ..
rm -rf tmp-repo
Ось конкретна команда sudo -u git git gc --aggressive --prune=now
важливо (запущено cron git gc
інакше має один надто довгий час обрізки 2 тижні).