Инкрементные резервные копии с пакетом git для всех веток

Какой самый простой способ делать инкрементные резервные копии git-репозитория с git bundle?

Если бы я просто хотел сделать резервную копию одной ветви, я мог бы сделать что-то вроде этого:

git bundle create foo last-backup..master
git tag -f last-backup master

Но что, если я хочу сделать резервную копию всего (включая все ветви)?


Чтобы ответить на вопросы в комментариях:

Строго говоря, мне не нужно использовать обычные Git-расслоения, если решение удовлетворяет следующим свойствам:

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

  • Размер файла приблизительно равен общему размеру коммитов Git с момента предыдущего резервного копирования. Изменения в двоичных файлах также эффективно хранятся.

  • Полная резервная копия + все инкрементные резервные копии с тех пор содержат все, что мне нужно для автоматического восстановления хранилища, включая все ветви.

(В качестве наивного примера простое создание архива tar с недавно измененными файлами в репозитории git не удовлетворяет второму требованию, если, например, произошла автоматическая сборка мусора.)

И в идеале я хотел бы также иметь систему, защищенную от идиотов:

  • Я могу взять практически любую полную резервную копию моего Git-репозитория, а также все последние инкрементные резервные копии, и я могу просто "извлечь" все из резервных копий, и репозиторий будет в актуальном состоянии. В частности, не имеет значения, есть ли частичное совпадение между полным и дополнительным резервным копированием.

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

4 ответа

Решение

(Мы обсуждали эту проблему с Юккой, это результат.)

Отборочные:

  1. Иметь последнюю резервную копию как backup.bundle
  2. Есть пульт backup это указывает на backup.bundle

Делать резервную копию:

  1. git fetch backup - просто чтобы убедиться, что мы в курсе
  2. git bundle create newbackup.bundle ^backup/A ^backup/B A B C
    • Это означает, что мы создаем пакет, который исключает все то, что уже было в пакете
    • Легко генерировать необходимое ^backup/Aаргументы от refs/remotes/backup/
    • Аналогично Aаргументы в стиле от refs/heads
  3. копия newbackup.bundle туда, где вы храните свои резервные копии
  4. замещать backup.bundle с newbackup.bundle так что вы знаете, где начать следующую инкрементную резервную копию

Восстановление:

  1. Иметь хранилище, которое либо пустое, либо представляет старую версию вашего хранилища.
  2. Для каждого файла резервной копии, в последовательности:
    1. git remote rm recovery
    2. git remote add recovery <name-of-bundle>
    3. git fetch recovery - вам нужно назвать пульт, чтобы это работало
  3. Теперь у вас должна быть доступна каждая ветка в 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: нет, это должно сработать, см. Комментарий Юкки ниже.

Другие вопросы по тегам