2011-02-01 2 views
32

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

+1

Единственная разница между репозиторием git на «сервере» (если есть разница) заключается в том, что репо на сервере, вероятно, голеное. Подумайте о другом ПК точно так же, как вы думаете о сервере. –

ответ

24

Вместо того, чтобы голый клон , Я предпочитаю делать bundle (см. «How can I email someone a git repository?»), который генерирует один файл, проще скопировать (например, на 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 
+1

@Cacovsky: Благодарим вас за редактирование и фиксированную ссылку. – VonC

22

См. this blog post "Synchronizing Git repositories without a server " (по Victor Costan).

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

Запуск путем создания хранилища на USB-флешку.

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

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

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

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

git push 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 
+1

Никогда не устанавливайте * полностью * по внешней ссылке: вы не знаете, как долго это будет продолжаться. С http://blog.stackoverflow.com/2009/06/stack-overflow-creative-commons-data-dump/ эта информация будет доступна навсегда. – VonC

+0

А, спасибо за это. Я очищу текст. – misha

+0

ли это, что первый «git clone --local» будет лучше, чем «git clone --no-hardlinks», чтобы четко указать, что это должна быть глубокая копия? –

5

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

I.e. слить repo2 со второго компьютера в ~/repo1, первый экземпляр repo2 к файловой системе repo1 в ~/repo2 (флэш-памяти, сетевой копии и т.д.), а затем вы можете использовать ответ на Git pulling changes between two local repositories:

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

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

+0

может ли кто-нибудь с большим знанием, чем я, подтвердить это? @sage, если я просто хочу создать резервную копию моего каталога (который содержит мой .git), скопировав его на USB-накопитель, этого было бы недостаточно? –

+2

@nutty - Прямое копирование отлично работает для перевода репо в его точное состояние, и я часто это делаю. Тем не менее, для некоторых случаев использования я считаю предпочтительным иметь возможность вытягивать/сливаться с одного места диска на другое (например, когда я редактировал места репо, и я хочу их синхронизировать). Гит восхитительно подходит в этом отношении. :-) – sage

0

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

Если я

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-устройства изменяется в зависимости от порта, в который я его вставляю.

Я затем запустить сценарий с содержимым, как этот

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-репозитория, и условный код выполняется только в том случае, если каталог существует.)

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

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

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

Другое дело, что довольно очевидно, но я не видел уже упоминалось, что для того, чтобы синхронизировать ПК A и B PC, вы должны были бы

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 

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

Смежные вопросы