Инкрементные резервные копии с пакетом git для всех веток
Какой самый простой способ делать инкрементные резервные копии git-репозитория с git bundle
?
Если бы я просто хотел сделать резервную копию одной ветви, я мог бы сделать что-то вроде этого:
git bundle create foo last-backup..master
git tag -f last-backup master
Но что, если я хочу сделать резервную копию всего (включая все ветви)?
Чтобы ответить на вопросы в комментариях:
Строго говоря, мне не нужно использовать обычные Git-расслоения, если решение удовлетворяет следующим свойствам:
Каждая инкрементная резервная копия представляет собой один файл. Я могу хранить его где-нибудь, и последующие инкрементные резервные копии не должны изменять этот файл.
Размер файла приблизительно равен общему размеру коммитов Git с момента предыдущего резервного копирования. Изменения в двоичных файлах также эффективно хранятся.
Полная резервная копия + все инкрементные резервные копии с тех пор содержат все, что мне нужно для автоматического восстановления хранилища, включая все ветви.
(В качестве наивного примера простое создание архива tar с недавно измененными файлами в репозитории git не удовлетворяет второму требованию, если, например, произошла автоматическая сборка мусора.)
И в идеале я хотел бы также иметь систему, защищенную от идиотов:
- Я могу взять практически любую полную резервную копию моего Git-репозитория, а также все последние инкрементные резервные копии, и я могу просто "извлечь" все из резервных копий, и репозиторий будет в актуальном состоянии. В частности, не имеет значения, есть ли частичное совпадение между полным и дополнительным резервным копированием.
Пакеты Git удовлетворяют все это очень хорошо, если мне нужно обрабатывать только одну ветку.
4 ответа
(Мы обсуждали эту проблему с Юккой, это результат.)
Отборочные:
- Иметь последнюю резервную копию как
backup.bundle
- Есть пульт
backup
это указывает наbackup.bundle
Делать резервную копию:
git fetch backup
- просто чтобы убедиться, что мы в курсеgit bundle create newbackup.bundle ^backup/A ^backup/B A B C
- Это означает, что мы создаем пакет, который исключает все то, что уже было в пакете
- Легко генерировать необходимое
^backup/A
аргументы отrefs/remotes/backup/
- Аналогично
A
аргументы в стиле отrefs/heads
- копия
newbackup.bundle
туда, где вы храните свои резервные копии - замещать
backup.bundle
сnewbackup.bundle
так что вы знаете, где начать следующую инкрементную резервную копию
Восстановление:
- Иметь хранилище, которое либо пустое, либо представляет старую версию вашего хранилища.
- Для каждого файла резервной копии, в последовательности:
git remote rm recovery
git remote add recovery <name-of-bundle>
git fetch recovery
- вам нужно назвать пульт, чтобы это работало
- Теперь у вас должна быть доступна каждая ветка в
refs/remotes/backup
Попробуйте использовать --since с --all.
Создайте первую резервную копию:
git bundle create mybundle-all --all
Сделать инкрементное резервное копирование:
git bundle create mybundle-inc --since=10.days --all
Инкремент должен содержать все коммиты по всем веткам, которые произошли за последние 10 дней. Убедитесь, что параметр --since возвращается достаточно далеко, иначе вы можете пропустить коммит. Git также откажется создавать пакет, если в этот период времени не было зафиксировано никаких коммитов, так что планируйте это.
Вы могли бы сделать
git clone --mirror <your_repo> my-backup.git
Это создаст голый репо со всеми ссылками.
Тогда вы могли бы периодически делать git push --mirror <my-backup>
,
Кажется, решение opqdonut не будет работать, потому что ^backup/A ^backup/B указывает только на последнюю инкрементную резервную копию. И на самом деле нужно исключить ссылки из всех предыдущих инкрементных резервных копий.
Нужно создать пульты для каждого из предыдущих комплектов.
UPD: нет, это должно сработать, см. Комментарий Юкки ниже.