2011-02-01 36 views
32

Tengo dos repositorios git en diferentes PC. Tengo algunas sucursales locales en cada uno de ellos. No quiero enviar estas sucursales al servidor remoto, solo mantenlas localmente. ¿Cómo puedo sincronizar sin usar una web? ¿Puedo comprimir el repositorio en una PC y pasar a otra? ¿Eso es seguro? ¿Tal vez puedo exportar los cambios más nuevos de todas las ramas?Cómo sincronizar dos repositorios git

+1

La única diferencia entre el repositorio de git en "el servidor" (si hay una diferencia) es que el repositorio en el servidor probablemente esté vacío. Piensa en la otra PC exactamente de la misma manera que piensas en el servidor. –

Respuesta

24

En lugar de hacer un clon desnuda , Prefiero hacer un bundle (ver "How can I email someone a git repository?"), que genera uno archivo, más fácil de copiar (en una memoria USB, por ejemplo)

La ventaja es que tiene algunas de las características de un repositorio simple: puede extraerlo o clonarlo.
Pero solo tiene que preocuparse por un archivo.

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

Esto va a definir un llamado "origin" remota en el repositorio resultante que le permite traer y tire del paquete. El archivo $GIT_DIR/config en R2 tendrá una entrada como esta:

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

Para actualizar el repositorio mine.git resultante, se puede recuperar o tirar después de reemplazar el paquete se almacena a /home/me/tmp/file.bundle con actualizaciones incrementales.

Después de trabajar un poco más en el repositorio original, puede crear un lote gradual para actualizar el otro repositorio:

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

A continuación, transfiere el paquete a la otra máquina para reemplazar /home/me/tmp/file.bundle, y sacar de eso.

machineB$ cd R2 
machineB$ git pull 
+1

@Cacovsky: gracias por la edición y el enlace fijo. – VonC

22

Ver this blog post "Synchronizing Git repositories without a server " (por Victor Costan).

Este post describe un método para empujar los cambios entre dos centros de almacenamiento sin necesidad de utilizar un servidor con conexiones de red a los anfitriones que tienen repositorios

Puesta en marcha mediante la creación de un repositorio en la memoria USB.

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

luego registrar el repositorio en la memoria USB como un repositorio remoto, y empujar la rama deseada a ella (si no quiere empujar maestro, el sustituto de su rama deseada).

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

En el futuro, puede tratar el repositorio USB como cualquier otro repositorio remoto. Solo asegúrese de que esté montado :) Por ejemplo, lo siguiente empuja nuevos cambios al repositorio USB.

git push usb 

En el extremo receptor, monte la memoria USB, y utilizar una dirección de fichero para el repositorio

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

algunos comandos útiles:

# 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

Nunca confíe * completamente * en un enlace externo: no sabe cuánto tiempo durará. Con http://blog.stackoverflow.com/2009/06/stack-overflow-creative-commons-data-dump/, esa información estará disponible para siempre. – VonC

+0

Ah, gracias por eso. Iré a limpiar el texto. – misha

+0

¿ese primer "git clone --local" sería mejor que "git clone --no-hardlinks" para aclarar explícitamente que tiene que ser una copia profunda? –

5

copia directa de un depósito a otro sistema de archivos es una alternativa al desnudo clon o agrupar. Después de copiar, puede configurar el repositorio copiado directamente como un control remoto local - no intuitivo como puede parecer el control remoto local - para captar e integrarse en el primer repositorio.

I.e. fusionar repo2 desde un segundo ordenador en ~/repo1, primera copia repo2 al sistema de archivos repo1 en ~/repo2 (lápiz de memoria, copia de la red, etc.) y luego se puede utilizar la respuesta a Git pulling changes between two local repositories:

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

Esto funciona porque the wikipedia article on git dice: "Un repositorio de Git - datos y metadatos - está completamente contenido dentro de su directorio, por lo que una copia normal del sistema (o renombrar, o eliminar) de un repositorio completo de Git es una operación segura. la copia es independiente y no conoce el original ".

+0

¿alguien con más conocimiento que yo puede confirmar esto? @sage si solo quiero hacer una copia de seguridad de mi directorio (que contiene mi .git) copiando y pegando en un dispositivo USB, ¿no sería suficiente? –

+2

@nutty: la copia directa funciona bien para transferir el repositorio en su estado exacto y a menudo hago eso. Sin embargo, para algunos casos de uso, me parece preferible poder tirar/fusionar de una ubicación de disco a otra (por ejemplo, cuando edité ambas ubicaciones de repositorio y quiero sincronizarlas). Git es deliciosamente complaciente en este sentido. :-) – sage

0

Me gustaría agregar un pequeño giro a las cosas. La información en otras publicaciones parece correcta, pero me gustaría mencionar algunas cosas adicionales que hago en la práctica.

Si hago

git remote -v 

conseguir información como esta

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) 

Básicamente he definido varios mandos a distancia con nombres USB en lugar de sólo uno como se sugiere desde la letra de unidad asignada a mi dispositivo USB Cambia dependiendo del puerto donde lo inserte.

luego ejecutar un script con contenidos como esto

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 

La intención es empujar todas las ramas y todas las etiquetas al repositorio USB si existe y donde quiera que sea. (. La bandera -d es la comprobación de la existencia del directorio del repositorio Git y código condicional sólo se ejecuta si el directorio existe)

La pregunta original dicho: Tengo algunas ramas locales en cada uno de ellos. No quiero enviar estas sucursales al servidor remoto, solo mantenlas localmente. ¿Cómo se puede sincronizar I ...

El empuje -todas y empuje --tags comando de sincronización hacer esto, asegurándose de que todas las ramas y las etiquetas son empujados al repositorio USB, incluso los nuevos que el repositorio USB no lo sabía. No hay incumplimiento para dominar o la necesidad de conocer los nombres de las ramas y manejarlas una a una.

Ejecuto esto con fines de copia de seguridad, así que solo he mostrado el lado positivo y he reducido el número de proyectos y repositorios.En realidad, realizo una copia de seguridad de múltiples proyectos en varias ubicaciones, pero son solo los elementos USB repetidos los que son relevantes aquí.

Otra cosa que es bastante obvio, pero que no he visto mencionado, es que con el fin de sincronizar la PC A y B de PC, que había necesidad de

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! 

O visto de otra manera, ir

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

para que finalmente las ramas y etiquetas sean las mismas en las dos máquinas.

Cuestiones relacionadas