Резервное копирование / репликация извлеченного репозитория git без снэпшотов - без rsync'а каталога .git - PullRequest
1 голос
/ 03 июня 2019

Локальный извлеченный репозиторий git должен быть отражен на резервную машину, то есть каталог .git и рабочее дерево.На этой резервной машине будет сделана файловая система снимков , чтобы обеспечить простое и мгновенное восстановление после произвольных неудач git [1].

Очевидным решением является использование rsync и все готово, но при регулярном запуске git gc создаются новые и разные большие .pack файлы, которые плохо воспроизводятся со снимками [2].Эта опция gc не может быть легко изменена для исходного репозитория.Также это будет означать, что rsync обходит все в подпапке .git/objects, замедляя его.

Было бы более элегантно использовать git напрямую (и просто перенести все уже переданные работы в пустой репозиторий).было бы легко), но это оставляет рабочее дерево.Серверная конфигурация репо receive.denyCurrentBranch = updateInstead не будет работать, потому что рабочее дерево может быть не чистым.

Будет что-то вроде git push 'ing, а затем rsync' с рабочим деревом плюс все в .git минус работа подпапки objects?В идеале, даже повторяющаяся перебазировка, слияние или выбор вишни будут воспроизведены.Я думал о серверных хуках [3] на post-receive, но они никогда не видят состояние рабочего дерева клиента.

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

2: Например, три ~ 10 строк коммитов и запуск gc привели к ок.Передается 500 МБ файлов.

3: перехватчики на стороне сервера означают, что репо нельзя восстановить с помощью простого scp -r, но это приемлемо.


ОБНОВЛЕНИЕ:

Кажется невозможным, как, например, jwz, уже обнаруженный в 2015 году [j], обходные пути:

[..], было 3½ предложений здесь:

  1. Полностью отключите файлы пакета и gc, что приведет к накоплению небольших файлов при каждом будущем изменении и в конечном итоге приведет к замедлению работы.gc.auto 0, gc.autopacklimit 0.

  2. Установите максимальный размер пакета на меньшее число, чтобы ни один файл пакета не становился слишком большим, а последующие слои различий объединялись в меньшиеупаковать файлы.pack.packSizeLimit.

  3. Особое мнение по поводу # 2: это не делает то, что вы думаете, а просто разбивает один большой файл пакета на N различных файлов с одинаковыми битами вих, поэтому вы ничего не сохранили.

  4. Если у вас уже есть один гигантский файл пакета, создайте рядом с ним файл .keep.Появятся новые файлы пакета, но они будут отличаться от сохраненного и, следовательно, меньше.

j: https://www.jwz.org/blog/2015/05/git-and-backups/

Ответы [ 2 ]

2 голосов
/ 04 июня 2019

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

Однако, сказав это, я призываю вас пересмотреть, хотите ли вы синхронизировать части рабочего дерева, например,в качестве индекса.Индекс не предназначен для передачи между компьютерами, поскольку он содержит такую ​​информацию, как номера индексов и временные метки файлов.Кроме того, модель безопасности репозитория Git предполагает, что рабочее дерево является доверенным, и единственными безопасными операциями, которые можно выполнять в ненадежном репозитории, являются клонирование и выборка.

Однако, если вы действительно хотите это сделатьТаким образом, вы можете использовать подход push-and-rsync.Лично я бы выбрал гораздо более простой подход - просто использовать rsync и съесть незначительное снижение производительности при перепаковке, поскольку это вряд ли будет распространено.По умолчанию git gc просто создает новый пакет с новыми объектами и не перепаковывает все существующие пакеты, если не существует более 10000 * (по умолчанию 50) пакетов, поэтому в 98% случаев вы простоrsync один новый пакет и удалить старые незакрепленные объекты, а также все, что находится в рабочем дереве.

1 голос
/ 05 июня 2019

Мой подход будет использовать git, а не заставлять его делать странные вещи. Это означает: используйте git push и git fetch в / из заднего хранилища. Чтобы также зафиксировать состояние рабочего дерева, вы можете сначала вызвать что-то вроде git stash push --all (или только --include-untracked вместо --all). Затем убедитесь, что вы отражаете refs/stash ref также в резервном хранилище. Поскольку git теперь записывает объекты для всего в рабочем дереве, эти объекты также могут быть перенесены в резервную копию.

...