2009-11-19 17 views
114

Normalmente trabajo en un servidor remoto a través de ssh (pantalla y vim), donde tengo un repositorio de Git. A veces no estoy conectado, así que tengo un repositorio separado (clonado desde mi control remoto) en mi computadora portátil.¿Cómo presionar a un repositorio de Git no desnudo?

Sin embargo, no puedo extraer de este repositorio en el lado remoto porque normalmente estoy detrás de un firewall o no tengo una IP pública.

He leído que debo enviar solo a un repositorio vacío. ¿Cómo debo enviar mis cambios a mi repositorio remoto?

+0

relacionados: http://stackoverflow.com/questions/12265729/git-config-receive-denycurrentbranch – prusswan

+2

tienen 2 repos remotos, uno desnudo y uno normal, y usan ganchos. parece una molestia, pero de acuerdo con [git ready] (http://gitready.com/advanced/2009/02/01/push-to-only-bare-repositories.html) y [la wiki oficial de git] (https : //git.wiki.kernel.org/index.php? title = Git_FAQ & oldid = 23811 # Why_won.27t_I_see_changes_in_the_remote_repo_after_.22git_push.22.3F), deberías ** presionar solo a un repositorio simple **. esta es probablemente la razón por la que la mayoría de los hosts git repo (por ejemplo, GitHub, Bitbucket) incluyen los ganchos post-recepción, por lo que puede enviar a un URL en su servidor que ejecute un script que ejecute, por ejemplo, 'git pull github master'. –

Respuesta

69

receive.denyCurrentBranch updateInstead, agregó in Git 2.3, también actualiza el árbol de trabajo del servidor si está limpio.

Así que si se asegura de que siempre se compromete antes de tirar localmente y mantiene un árbol de trabajo limpio en el servidor (lo que debe hacer para evitar conflictos de fusión), entonces esta opción es una buena solución.

Ejemplo de uso:

git init server 
cd server 
touch a 
git add . 
git commit -m 0 
git config --local receive.denyCurrentBranch updateInstead 

cd .. 
git clone server local 
cd local 
touch b 
git add . 
git commit -m 1 
git push origin master:master 

cd ../server 
ls 

Salida:

a 
b 
+6

Esta debería ser realmente la respuesta aceptada. Es súper simple y funciona genial, como era de esperar. ¡Gracias! – mav

+1

Excelente forma de representar –

+1

Buena solución que mantiene todo tal como está. –

140

mejor opción

Probablemente el más limpio, menos confuso, y la forma más segura de empujar en su repositorio remoto no desnuda, es presionar a las ramas dedicadas en el mando a distancia que representan sus ramas portátiles.

Veamos el caso más simple, y supongamos que tiene una sola rama en cada repositorio: maestro. Cuando presiona hacia el repositorio remoto desde su computadora portátil, en lugar de presionar master -> master, presione master -> laptop-master (o un nombre similar). De esta forma, la inserción no afecta a la rama maestra que está actualmente desprotegida en el repositorio remoto. Para hacerlo desde el ordenador portátil, el comando es bastante simple:

git push origin master:laptop-master 

Esto significa que la rama local master será empujado a la rama llamada "portátil-master" en el repositorio remoto. En su repositorio remoto, tendrá una nueva rama llamada "laptop-master" que luego podrá fusionar en su maestro remoto cuando esté listo.

opción alternativa

También es posible simplemente empuje principal -> maestro, pero empujando a la rama actualmente desprotegido de un acuerdo de recompra no desnuda no es recomendable, ya que puede ser confuso si no entiendo lo que está pasando. Esto se debe a que presionar en una rama desprotegida no actualiza el árbol de trabajo, por lo que al marcar git status en la rama extraída que se insertó se mostrarán exactamente las diferencias opuestas a las que se presionaron más recientemente. Sería especialmente confuso si el árbol de trabajo estuviera sucio antes de que se realizara el empuje, que es una gran razón por la cual no se recomienda.

Si quieres probar simplemente empujando maestro -> maestro, a continuación, el comando es simplemente:

git push origin 

Pero cuando vuelva al repositorio remoto, lo más probable quieren hacer un git reset --hard HEAD a conseguir que el árbol de trabajo esté sincronizado con el contenido que se envió. Esto puede ser peligroso, porque si hay no confirmado cambios en el árbol de trabajo remoto que desea mantener, los borrará. ¡Asegúrese de saber cuáles son las consecuencias de esto antes de probarlo, o al menos hacer primero una copia de seguridad!

EDIT Desde Git 2.3, puede utilizar "push-to-deploy" git push: https://github.com/blog/1957-git-2-3-has-been-released. Pero empujar a una rama separada y luego fusionar suele ser mejor, ya que realiza una fusión real (por lo tanto, funciona con cambios no confirmados como lo hace merge).

+1

¿Es posible automatizar la bifurcación después de presionar el equipo portátil? – rdoubleui

+3

@rdoubleui: ¿Quiso decir "automatizar * fusionar *"? Si es así, no, no es posible automatizar la fusión porque no se garantiza que las fusiones sean posibles sin intervención humana. Puede haber conflictos que deben resolverse. –

+0

Quise decir "automatizar la fusión", sí. Gracias, todavía estoy aprendiendo. – rdoubleui

13

Yo sugeriría que tenga un repositorio vacío y un repositorio local (no puro) en su servidor. Podrías impulsar los cambios de la computadora portátil al repo al descubierto del servidor y luego pasar de ese repositorio desnudo al repositorio de trabajo del servidor.La razón por la que digo esto es porque es posible que tenga muchas ramas completas/incompletas en el servidor que deseará replicar en la computadora portátil.

De esta forma, no tiene que preocuparse por el estado de la rama desprotegida en el repositorio de trabajo del servidor mientras se realizan cambios en el servidor.

+0

Tan simple como eso. –

1

Otra opción es configurar un túnel SSH inverso, de modo que se puede tirar en lugar de empujar.

# start the tunnel from the natted box you wish to pull from (local) 
$ ssh -R 1234:localhost:22 [email protected] 

# on the other box (remote) 
$ git remote add other-side ssh://[email protected]:1234/the/repo 
$ git pull other-side 

Y si desea que el túnel para ejecutarse en segundo plano

$ ssh -fNnR 1234:localhost:22 [email protected] 
0

que puede hacer:

$git config --bool core.bare true

esto se puede hacer en el repositorio desnudo o central, de modo que aceptará cualquier archivo que sea enviado desde repositorios no desnudos. Si hace esto en un repositorio no desnudo, entonces no podemos enviar ningún archivo desde el repositorio no desnudo al simple.

Si está practicando GIT creando repo central y non bare en PC, es posible que no muestre los archivos empujados en algunas PC, pero se ha pulsado. puedes verificarlo ejecutando.

$git log in central repo.

Aparte de presionar a GitHub, mostrará los archivos allí.

Cuestiones relacionadas