Usando Git en múltiples sistemas sin acceso a la red

84

Quiero usar el control de versiones pero, por razones de seguridad, el servidor en el que estoy trabajando no tiene acceso a Internet: solo puedo mover archivos en una unidad flash USB. ¿Puedo seguir usando Git con esta configuración? ¿Puedo crear pequeños parches que puedo aplicar en un repositorio de Git?

Tutu Kaeen
fuente
65
Su título dice que no hay acceso a la red, su pregunta dice que no hay acceso a Internet; Una gran diferencia.
tkausl
77
@TutuKaeen Puede tener una red local que no esté conectada a Internet. Entonces, en lugar de github.com , configura el servidor git en, por ejemplo, 192.168.1.100 y todo lo demás funciona igual.
Agent_L
12
@TutuKaeen: La pregunta crítica es si la comunicación de red directa (o indirecta) es posible entre las dos máquinas. Entonces, en su caso, ¿ambas máquinas están conectadas en red, pero las redes están separadas? En ese caso, edite esa información en su pregunta.
sleske
15
@TutuKaeen Su pregunta sigue sin estar clara. Dices que quieres usar el control de versiones, pero en tus comentarios requieres que te ayude a implementarlo en producción. Estos problemas no siempre se superponen. Creo que ahora tiene buenas respuestas a continuación, pero en el futuro sería útil que su pregunta fuera más exhaustiva sobre sus requisitos, que parecen ser: "Quiero usar el control de versiones, mi máquina de desarrollo no tiene acceso a Internet, tiene acceso a la red pero no a la máquina de producción, y quiero saber cómo obtener el código del control de versiones en la máquina de producción ".
DavidS
44
Simplemente parece extraño usar el término serverpara una máquina que no está conectada a ninguna red. Podría ser una red local incluso sin acceso a Internet, pero aún así es una red.
Patrick Gregorio el

Respuestas:

157

Claro, no hay nada sobre Git que requiera un protocolo particular. Recién salido de la caja, el cliente estándar admite HTTP (S), SSH, el protocolo Git personalizado y, lo que es más importante, el protocolo local . Eso solo toma una ruta a un .gitdirectorio local , que puede estar dentro del directorio de trabajo ( /path/to/project/.git) o solo un directorio simple ( /path/to/project.git), aunque la denominación es solo una convención.

Esto significa que, por supuesto, puede agregar una unidad flash como control remoto:

git remote add origin /mnt/flashdrive/foo.git

o en Windows:

git remote add origin F:\foo.git

O incluso agréguelo como un control remoto adicional con un nombre diferente (si prefiere originapuntar hacia un servidor de Internet en algún lugar):

git remote add flashdrive /mnt/flashdrive/foo.git

Luego puede simplemente empujar / tirar hacia / desde este control remoto como cualquier otro.

Si lee la documentación , notará que también hay un file://protocolo que se comporta de manera ligeramente diferente. Se recomienda usar una ruta local, ya que hará uso de algunas optimizaciones adicionales: si usa el file://protocolo, git usará algunos componentes de red estándar (para comunicarse con el disco local), que es más lento.

Mover
fuente
50
Para agregar a esta respuesta excepcional, también puede valer la pena investigar usando un repositorio 'desnudo' en la unidad flash. Los repositorios "desnudos" no tienen un árbol que funcione, por lo que eliminan una categoría de problemas potenciales cuando se usan como un "punto de autoridad" compartido, que suena como el caso de uso del OP.
Iron Gremlin
55
El file://también es un poco más flexible. Le permite usar algunas características (como clones poco profundos) que no puede utilizar con una ruta local.
Austin Hemmelgarn
1
@IronGremlin ¿Podría ampliar esta noción de "punto de autoridad compartida"? No soy un experto en Git y tengo curiosidad por saber a qué te refieres.
Carreras de ligereza en órbita el
2
@LightnessRacesinOrbit: este es un tema bastante denso, pero, básicamente, git se distribuye, por lo que todos obtienen su propia historia. A puede pedirle a B su versión de la historia, pero C no lo sabe a menos que alguien se lo diga. Tener un único repositorio para almacenar la historia "autorizada" significa que D actúa como un centro de intercambio de historias. Entonces, A le dice a D sobre los cambios, y B y C saben hablar con D para mantenerse al día, en lugar de hacer cosas de canal lateral entre ellos. Caso en cuestión, si el servidor de OP es C y la unidad flash es D, se asegura de que el servidor no quede fuera de las interacciones A / B.
Iron Gremlin
66
@LightnessRacesinOrbit Es importante tener en cuenta aquí que desnudo no tiene que significar autoridad, solo es útil en ese contexto. Por ejemplo, también es útil porque, al carecer de un árbol de trabajo, es una huella de espacio en disco (o ancho de banda) más pequeña. Esto solía ser muchísimo más importante de lo que es ahora, pero aún surge.
Iron Gremlin
46

En una sola computadora, no se necesita nada especial. Ejecute git initen su directorio deseado y trabaje con Git como lo haría normalmente.

Para sincronizar un repositorio en varias computadoras, hay varios métodos.

Método 1a (sin red en absoluto): puede crear un 'repositorio desnudo' en el dispositivo USB, luego empujarlo y extraerlo como lo haría con cualquier otro repositorio remoto. En otras palabras, las operaciones de repositorio a través de rutas locales no son diferentes de las operaciones a través de URL SSH o HTTPS.

  1. Cree un repositorio 'remoto':

    $ git init --bare /mnt/Stick/Repositories/Large_Project.git
    
  2. En la computadora 1, empuje todo hacia ella:

    $ cd ~/Large_Project
    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git push usb master
    
  3. En la computadora 2, bueno, igual que siempre.

    $ git remote add usb /mnt/Stick/Repositories/Large_Project.git
    $ git pull usb
    

(También puede insertar / recuperar / extraer directamente de una URL o ruta).

Método 1b (red interna): si tiene un servidor interno con SSH disponible, y si tiene instalado Git, puede hacer lo mismo que anteriormente , solo especifique una dirección SSH usando la sintaxis [user@]host:patho ssh://[user@]host/path.

  1. Cree un repositorio 'remoto' ejecutándose git init --bare <somepath.git>en el servidor designado (a través de SSH).

  2. En la computadora 1, de la misma manera que se demostró anteriormente.

    $ git remote add origin myserver.example.com:Gits/Large_Project.git
    

    O si lo prefieres:

    $ git remote add origin ssh://myserver.example.com/Gits/Large_Project.git
    
  3. En la computadora 2, nuevamente lo mismo que el método 1a.


Método 2: puede crear 'paquetes de transferencia' que archiven una lista dada de confirmaciones en un solo archivo.

Desafortunadamente, los comandos de paquete no recuerdan automáticamente lo que ya se incluyó la última vez, por lo que se necesita etiquetado manual o mantenimiento de notas. Solo tomaré los ejemplos del manual de git-bundle.

  1. En la computadora 1, cree un paquete de toda la rama:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle master
    $ git tag -f last-bundled master
    
  2. En la computadora 2, extraiga del paquete como si fuera un repositorio:

    $ cd ~/Large_Project
    $ git pull /mnt/Stick/Project.bundle
    

Los paquetes subsiguientes no necesitan empacar el conjunto master, sino que pueden empacar solo los commits recién agregados last-bundled..master.

  1. En la computadora 1, cree un paquete de los commits recién agregados:

    $ cd ~/Large_Project
    $ git bundle create /mnt/Stick/Project.bundle last-bundled..master
    $ git tag -f last-bundled master
    
  2. Lo mismo que arriba.

Gravedad
fuente
en realidad no sería malo para mis propósitos, también en git nada es "primario" ya que cada repositorio tiene toda la historia, por lo que puedes recrearlo cada vez que algo sale mal
Tutu Kaeen
manual tagging or note-keeping is needed, una opción a menos que el repositorio sea muy grande es: git bundle create my.bundle --alldebería contener todo
birdspider
Me gusta más esta respuesta, ya que es más ilustrativa a pesar de que la respuesta aceptada y esto dice lo mismo.
Rystraum
¿Cuál es el significado de la opción "desnuda"?
Carreras de ligereza en órbita el
1
Crea un repositorio que es solo la base de datos (lo que normalmente encontraría en la .git/carpeta oculta), sin un 'árbol de trabajo' (los archivos editables). Es la forma preferida para los repositorios que usted tiene git push.
Grawity
20

git bundle create

Uno de los métodos es usar almacenamiento externo para intercambiar datos entre repositorios es git bundle . De esta manera, solo tiene archivos únicos para cada transferencia, no repositorios intermedios de Git.

Cada "git push" se convierte en la creación de un archivo, "git fetch" recupera cosas de ese archivo.

Sesión de demostración

Crear el primer repositorio y hacer el primer "empuje"

gitbundletest$ mkdir repo1

gitbundletest$ cd repo1

repo1$ git init
Initialized empty Git repository in /tmp/gitbundletest/repo1/.git/
repo1$ echo 1 > 1 && git add 1 && git commit -m 1
[master (root-commit) c8b9ff9] 1
 1 file changed, 1 insertion(+)
 create mode 100644 1

repo1$ git bundle create /tmp/1.bundle master HEAD
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 384 bytes | 384.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)

"clonación" al segundo repositorio (es decir, la segunda computadora):

gitbundletest$ git clone /tmp/1.bundle repo2
Cloning into 'repo2'...
Receiving objects: 100% (3/3), done.

gitbundletest$ cd repo2/

repo2$ cat 1
1

Haciendo algunos cambios y "empujándolos" a otro archivo de paquete:

repo2$ echo 2 > 1 && git add 1 && git commit -m 2
[master 250d387] 2
 1 file changed, 1 insertion(+), 1 deletion(-)

repo2$ git bundle create /tmp/2.bundle origin/master..master origin/HEAD..HEAD
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 415 bytes | 415.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)

"tirar" cambia al primer repositorio:

repo2$ cd ../repo1

repo1$ git pull /tmp/2.bundle 
Receiving objects: 100% (3/3), done.
From /tmp/2.bundle
 * branch            HEAD       -> FETCH_HEAD
Updating c8b9ff9..250d387
Fast-forward
 1 | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

repo1$ cat 1
2

A diferencia del primer paquete, el segundo contiene solo un historial parcial de Git y no es directamente clonable:

repo1$ cd ..

gitbundletest$ git clone /tmp/2.bundle repo3
Cloning into 'repo3'...
error: Repository lacks these prerequisite commits:
error: c8b9ff94942039469fa1937f6d38d85e0e39893a 
fatal: bad object 250d38747656401e15eca289a27024c61e63ed68
fatal: remote did not send all necessary objects

Hay una desventaja en el uso de paquetes que necesita para especificar manualmente qué rango de confirmaciones debe contener cada paquete. A diferencia git push, git bundleno realiza un seguimiento de lo que estaba en el paquete anterior, debe ajustarlo manualmente refs/remotes/origin/mastero los paquetes serían más grandes de lo que podrían ser.

Vi.
fuente
No olvide mencionar la --allbandera para obtener todo. Si el repositorio es lo suficientemente pequeño, este es el proceso más simple, ya que simplemente transfieres todo cada vez. Simplemente no pierda el dispositivo de memoria, ¡probablemente el mayor problema de seguridad!
Philip Oakley
7

Primero debes instalar Git . Luego, para crear un nuevo repositorio, ejecute dentro de la carpeta que ha copiado:

git init

Luego, puede agregar los archivos con los que desea controlar la versión git add(agregar -apara todos los archivos) y comenzar a confirmar los cambios ( git commit).

No tiene que presionar a ningún control remoto, ya que puede trabajar en su historial local ( git log).

Para más información, consulte:


Empujar / tirar sin internet

Usando el git pushcomando, es posible pasar SSH (usando conexión local, intranet):

git remote add server ssh://[user@]host.xz[:port]/path/to/dev/repo.git/
git push server

o empujando a la carpeta:

git push /mnt/usb/my_repo

Esto supone que tiene dos copias de su repositorio.

Lo mismo con tirar, p. Ej.

git pull /mnt/usb/my_repo

Parchear

Para aplicar parches, puede usar el patchcomando o git apply.

Consulte: Crear parches o archivos diff desde el repositorio git y aplicarlo a otro repositorio git diferente .

kenorb
fuente
5

Puedes usar Git localmente también. Luego, sus confirmaciones solo se almacenan localmente, y todavía tiene control de versiones (y puede diferir / fusionar, etc.), pero simplemente no puede acceder al repositorio desde cualquier otra computadora.

Puede iniciar un repositorio local de Git ejecutándose git initen su carpeta local. Como se describe aquí .

dhae
fuente
3
que sé, pero quiero trabajar en otra computadora y aplicarlo a los archivos en el servidor sin acceso a Internet
Tutu Kaeen
2
@TutuKaeen No veo nada de malo en tener el repositorio en una unidad flash y simplemente clonarlo / sincronizarlo en discos duros de diferentes computadoras. Sin embargo, "servidor sin acceso a Internet" suena extraño, el objetivo de un servidor es proporcionar un servicio, la mayoría de las veces el servicio está relacionado con las redes (pero no siempre, de hecho).
AnonymousLurker
2
@dhae: tómese un momento para proporcionar más detalles sobre cómo usar Git localmente. Solo indicar que se puede hacer no es una respuesta tan útil.
Ramhound
2
@anonymousLurker el servicio está sirviendo datos a una red cerrada en una institución muy importante. Simplemente no sirve nada para Internet, ya que los datos son muy delicados y solo para los empleados.
Tutu Kaeen
1
@TutuKaeen: Si no tiene ningún acceso a la red, siempre se puede ejecutar su propio servidor de Git a través de SSH. Hay más en Git que solo GitHub.
Grawity