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