Разделение файла 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
,