Разделение файла Git Bundle

Есть ли способ разбить файл Git Bundle? Например, repo.bundle1 и repo.bundle2, каждый из которых содержит половину репо. Портативный комплект слишком велик для переноса.

Как еще я могу приблизиться к этому, предполагая, что максимальный размер, разрешенный для передачи, не может быть изменен.

2 ответа

Решение

Связки могут быть добавочными.

У них не может быть висячих коммитов, поэтому вам нужно сыграть в игру, если вы хотите постепенно объединить существующую ветку.

Они должны применяться "по порядку", чтобы при применении пакета к нему могли привязываться родители его корневых коммитов. (Может быть способ обойти это с мелкими репозиториями, но если вы пытаетесь в конечном итоге реконструировать весь репо, вам не стоит об этом беспокоиться.)

И, конечно, если какой-либо один коммит слишком велик (например, из-за фиксации очень большого файла), это будет проблемой.

Скажи у тебя

       x -- x -- x <--(branch1)
      /
A -- B -- C -- D -- E -- F -- G -- H -- I -- J <--(master)
                \      /
                 o -- o <--(branch2)

И скажем, вы хотите разбить это на связки не более 3 коммитов. Итак, начнем с корня. Мы собираемся постепенно перемещать master ветвь, так что давайте отслеживать текущую позицию.

git checkout master
git tag real_master

Теперь мы ищем идентификатор SHA для C (или найдите другое имя, которое относится к Cкак в этом случае master~7) а потом

git reset --hard master~7

Обратите внимание, что я использую жесткий сброс; в этом, вероятно, нет необходимости, но я предполагаю, что вы можете сделать это из репозитория с чистым деревом операций, и в этом случае выполнение жесткого сброса сохраняет все в хороших, простых состояниях (в любом случае, как я вижу).

Мы готовы создать наш первый комплект

git bundle create 0.bundle master

Этот комплект включает Bчто является корнем для branch1так что мы можем связать branch1 сейчас.

git bundle create 1.bundle master..branch1

Это эквивалентно

git bundle create 1.bundle ^master branch1

В любом случае, мы говорим, что принимающий репо уже имеет ocmmits, достижимые из masterтак что только x коммиты будут размещены в этом пакете.

Может показаться, что D, E, F следующий логический шаг; но F зависит от o совершает в brnach2, Так что на самом деле следующая логическая вещь будет в комплекте branch2 вместе с D, Так как у нас еще есть master в C мы можем сказать

git bundle create 2.bundle master..branch2

Теперь нам нужно двигаться master в G так что мы можем связать E, F, а также G, Убедитесь, что мы на master а также

git reset --hard real_master~3
git bundle create 3.bundle ^branch2 ^master~3 master

Здесь я отмечаю, что и старая история магистрали и branch2 история достижима от master (путем слияния в F), но так как они оба уже связаны, я исключаю их обоих.

В заключение,

git reset --hard real_master
git tag -d real_master
git bundle create 4.bundle master~3..master

На практике вы, вероятно, будете использовать более 3 коммитов на пакет. Если у вас есть слишком большая боковая ветвь, вы можете разбить ее, используя ту же технику, которую мы использовали для сегментации master в этом примере.

Теперь вы можете передавать их независимо друг от друга и извлекать (или извлекать) из них, чтобы восстановить репо на другом конце.

UPATES

Два дополнительных примечания:


Во-первых, по сравнению с предложением ElpieKay использовать dd а также catУ вышеуказанного подхода есть свои плюсы и минусы.

Это зависит только от самого Git (хотя утилиты, необходимые для dd/cat подход обычно поставляется с мерзавцем).

Отдельные файлы комплекта полезны сами по себе, тогда как если вы сегментируете файл с помощью dd Вы должны восстановить все части, чтобы убедиться, что у вас есть полезный комплект. Это также означает, что вы можете сохранить пакеты и объединить их с дополнительными пакетами, которые вы создадите позже (по мере того, как происходит больше изменений); но это будет иметь значение только в том случае, если вам нужно создать еще один новый удаленный репозиторий с нуля.

На самом деле, просто отправка инкрементных изменений туда-сюда, где обе стороны уже имеют общую базовую линию коммитов, является основным вариантом использования пакетов. Таким образом, вы можете решить использовать dd/cat подход к первоначальному созданию удаленного репо, затем использовать инкрементные пакеты для последующего обмена обновлениями.

Самые большие преимущества dd/cat подход заключается в том, что он очень прост / скриптов (то есть прост, если инструменты под рукой), в то время как вы должны подумать о том, как разделить коммиты для вышеупомянутого подхода; а также dd подход может разделить один, неприятно большой коммит, если он окажется одним.


Я также забыл упомянуть, что вы можете перечислить несколько веток для включения в пакет. Так, например, если ваш порог был больше похож на 8 коммитов на пакеты, вы могли бы

1) Переместить master в E

2) связка master а также branch1 как 0.bundle

3) Переместить master вернуться к J

4) связка master исключая master~5 как 1. расслоение

и будет сделано.

Команда dd Можно разбить файл на несколько частей. cat можно объединить части обратно в одно целое.

Предположим, мы находим, что repo.bundle 1466712 К, около 1,4 г, du repo.bundle, И предположим, что ограничение составляет 1 г. Мы можем разделить repo.bundle в 2 файла, один 700 м, а другой чуть более 700 м, так что они могут быть переданы.

dd if=repo.bundle bs=1048576 count=700 skip=0 of=repo.bundle1
dd if=repo.bundle bs=1048576 skip=700 of=repo.bundle2

Единица bs так байт 1048576 является 1m, 700 означает 700 блоков. skip количество пропущенных блоков. Итак, первый dd пишет первые 700*1048576 байт repo.bundle в repo.bundle1 а второй dd пропускает первые 700*1048576, а затем записывает остальные в repo.bundle2,

После того, как эти два файла перенесены на другую машину, используйте cat объединить их:

cat repo.bundle1 repo.bundle2 > repo.bundle

Обратите внимание, что последовательность файлов после cat это важно. Мы можем использовать md5sum проверить, если комбинированный repo.bundle то же самое с происхождением. Если два файла все еще слишком велики, мы можем разбить исходный файл на несколько частей. Будь осторожен с skip каждого dd,

dd, cat, du, md5sum также доступны в git-bash,

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