Как синхронизировать два хранилища git

У меня есть два репозитория git на разных ПК. У меня есть несколько локальных веток на каждом из них. Я не хочу отправлять эти ветки на удаленный сервер, просто держите их локальными. Как я могу синхронизировать, не используя веб? Могу ли я просто закрепить архив на одном ПК и перейти на другой? Это безопасно? Может быть, я могу экспортировать как можно новые изменения из каждой ветки?

Ответ 1

Вместо того, чтобы делать голой клон, я предпочитаю делать bundle (см. "Как отправить сообщение кому-то в хранилище git?" ), который генерирует один файл, который легче копировать (например, на USB-накопителе)

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

machineB$ git clone /home/me/tmp/file.bundle R2

В результирующем репозитории будет определяться удаленный объект, называемый "origin", который позволяет извлекать и извлекать из пакета. Файл $GIT_DIR/config в R2 будет иметь следующую запись:

[remote "origin"]
    url = /home/me/tmp/file.bundle
    fetch = refs/heads/*:refs/remotes/origin/*

Чтобы обновить результирующий файл mine.git, вы можете извлечь или вытащить после замены пакета, хранящегося в /home/me/tmp/file.bundle, с инкрементными обновлениями.

После работы в исходном репозитории вы можете создать инкрементный пакет для обновления другого репозитория:

machineA$ cd R1
machineA$ git bundle create file.bundle lastR2bundle..master
machineA$ git tag -f lastR2bundle master

Затем вы переносите связку на другой компьютер, чтобы заменить /home/me/tmp/file.bundle, и вытащите из него.

machineB$ cd R2
machineB$ git pull

Ответ 2

См. это сообщение в блоге "Синхронизация репозиториев Git без сервера" (Виктор Костан).

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

Запустите создание репозитория на USB-накопителе.

mkdir /path/to/usb/stick/repository.git
git clone --local --bare . /path/to/usb/stick/repository.git

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

git remote add usb file:///path/to/usb/stick/repository.git
git push usb master

В будущем вы можете рассматривать репозиторий USB как любой другой удаленный репозиторий. Просто убедитесь, что он смонтирован:) Например, следующее перемещает новые изменения в репозиторий USB.

git push usb

На принимающей стороне смонтируйте USB-накопитель и используйте URL-адрес файла для репозитория

file:///path/to/usb/stick/repository.git

Несколько удобных команд:

# cloning the repository on the USB stick
git clone file:///path/to/usb/stick/repository.git
# updating a repository cloned from the USB stick using the above command
git pull origin
# adding the USB stick repository as a remote for an existing repository
git remote add usb file:///path/to/usb/stick/repository.git
# updating from a remote repository configured using the above command
git pull usb master

Ответ 3

Прямая копия репозитория в другую файловую систему является альтернативой голой клону или связыванию. После копирования вы можете установить скопированное репо прямо как локальный пульт - неинтуитивный, как может показаться местным удаленным - для извлечения и слияния в первый репозиторий.

т.е. для объединения repo2 со второго компьютера в ~/repo1, сначала скопируйте repo2 в файловую систему repo1 на ~/repo2 (карта памяти, сетевая копия и т.д.), а затем вы можете использовать ответ Git вытягивание изменений между двумя локальными репозиториями:

~/repo1 $ git remote add repo2 ~/repo2
~/repo1 $ git fetch repo2
~/repo1 $ git merge repo2/foo

Это работает, потому что статья wikipedia в git гласит: "Репозиторий Git - данные и метаданные - полностью содержит в своей директории, поэтому обычная копия системного уровня (или переименовать или удалить) всего хранилища Git является безопасной операцией. Полученная копия не зависит от оригинала и не знает его."

Ответ 4

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

Если я делаю

git remote -v

Я получаю такую ​​информацию

USB_F   file:///f/Git_repositories/projectname.git (fetch)
USB_F   file:///f/Git_repositories/projectname.git (push)
USB_G   file:///g/Git_repositories/projectname.git (fetch)
USB_G   file:///g/Git_repositories/projectname.git (push)

В основном я определил несколько пультов с именами USB, а не только один, как было предложено, так как буква диска, выделенная для моего устройства USB, изменяется в зависимости от порта, в который я его вставляю.

Затем я запускаю script с содержимым, подобным этому

cd /path/to/projectname

if [ -d /f/Git_repositories/projectname.git ] 
then
    git push USB_F --all
    git push USB_F --tags
fi
if [ -d /g/Git_repositories/projectname.git ] 
then
    git push USB_G --all
    git push USB_G --tags
fi

Цель состоит в том, чтобы выталкивать все ветки и все теги в репозиторий USB, если он существует и где он когда-либо был. (Флаг -d проверяет наличие каталога git репозитория, и условный код выполняется только в том случае, если каталог существует.)

Первоначальный вопрос: У меня есть некоторые локальные ветки на каждом из них. Я не хочу отправлять эти ветки на удаленный сервер, просто держите их локальными. Как синхронизировать...

Команда push -all и push -tags выполняет эту синхронизацию, следя за тем, чтобы все ветки и теги были перенесены в репозиторий USB, даже новые, которые в хранилище USB не было. По умолчанию не требуется мастерство или нужно знать имена ветвей и обрабатывать их один за другим.

Я запускаю его для целей резервного копирования, поэтому я только показываю то, что нажимает, и уменьшает количество проектов и репозиториев. На самом деле я резервирую несколько проектов для нескольких местоположений, но здесь важны только повторяющиеся элементы USB.

Еще одна вещь, которая довольно очевидна, но о которой я не упоминал, заключается в том, что для синхронизации ПК A и ПК B вам нужно

1. sync PC A and the USB device
2. sync PC B and the USB device
3. sync PC A and the USB device again!

Или иначе, пойдите,

PC A -> USB -> PC B
PC B -> USB -> PC A

так что в конечном счете ветки и метки на обеих машинах одинаковы.