¿Cómo pasar a un repositorio Git no descubierto?

150

Por lo general, trabajo en un servidor remoto a través de ssh (pantalla y vim), donde tengo un repositorio de Git. A veces no estoy en línea, así que tengo un repositorio separado (clonado desde mi control remoto) en mi computadora portátil.

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

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

woky
fuente
3
tener 2 repositorios remotos, uno desnudo y otro normal, y usar ganchos. parece una molestia, pero de acuerdo con git ready y el wiki oficial de git , solo debes presionar para obtener un repositorio desnudo . esta es probablemente la razón por la cual la mayoría de los hosts de repositorio de git (por ejemplo, GitHub, Bitbucket) incluyen ganchos posteriores a la recepción, por lo que puede PUBLICAR en una URL en su servidor que ejecuta un script que se ejecuta, por ejemplo git pull github master.
Jake Berger

Respuestas:

137

receive.denyCurrentBranch updateInstead

Esta opción se agregó en Git 2.3 , y hace que el servidor actualice su árbol de trabajo si está limpio.

Por lo tanto, si se asegura de comprometerse siempre antes de extraer localmente y mantener 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.

Uso de la muestra:

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
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
¿es posible empujar sin crear un repositorio desnudo como lo hace
heroku?
2
@ANinJa No entiendo, ¿no es eso exactamente lo que hace mi ejemplo?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
es --localopcional?
Yukulélé
@ Yukulélé --localafecta solo al directorio actual, --globalafecta a todos los repositorios de git con ~/.gitconfig, mira man git-config.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
gracias @CiroSantilli 新疆 改造 中心 六四 事件 法轮功 después de leer el documento, confirmo que no es necesario "(puedes decir --local pero ese es el valor predeterminado)"
Yukulélé
146

Mejor opción

Probablemente la forma más limpia, menos confusa y más segura de ingresar a su repositorio remoto no desnudo, es empujar a ramas dedicadas en el control remoto que representan las ramas de su computadora portátil.

Veamos el caso más simple y supongamos que tiene solo una rama en cada repositorio: maestro. Cuando presiona al 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 actualmente desprotegida en el repositorio remoto. Para hacer esto desde la computadora portátil, el comando es bastante simple:

git push origin master:laptop-master

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

Opción Alterna

También es posible simplemente presionar master -> master, pero generalmente no se recomienda presionar a la rama actualmente desprotegida de un repositorio no descubierto, porque puede ser confuso si no comprende lo que está sucediendo. Esto se debe a que empujar a una rama desprotegida no actualiza el árbol de trabajo, por lo que git statusal registrar la rama desprotegida que se introdujo se mostrarán exactamente las diferencias opuestas a lo que se empujó más recientemente. Sería especialmente confuso si el árbol de trabajo estuviera sucio antes de realizar el empuje, lo cual es una gran razón por la cual no se recomienda.

Si quieres probar simplemente presionando master -> master, entonces el comando es solo:

git push origin

Pero cuando regrese al repositorio remoto, lo más probable es que desee hacer un git reset --hard HEADpara sincronizar el árbol de trabajo con el contenido que se envió. Esto puede ser peligroso , porque si hay cambios no confirmados en el árbol de trabajo remoto que desea mantener, los eliminará. ¡Asegúrese de saber cuáles son las consecuencias de esto antes de intentarlo, o al menos haga una copia de seguridad primero!

EDITAR 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 hace una fusión real (por lo tanto, funciona con cambios no confirmados al igual que la fusión).

Dan Molding
fuente
1
¿Es posible automatizar la ramificación después de presionar el laptop-master?
rdoubleui
3
@rdoubleui: ¿Quiso decir "automatizar la fusión "? Si es así, no, no es posible automatizar la fusión porque no se garantiza que las fusiones sean posibles sin la intervención humana. Puede haber conflictos que deben resolverse.
Dan Moulding
77
en versiones posteriores (?), git config receive.denyCurrentBranch ignoredebe hacerse antes de
pasar a repositorios
3
Gran respuesta @ DanMoulding, gracias. @rdoubleui: siempre puedes guardar una línea de comando como la siguiente como una función bash:git push origin master:laptop-master && ssh user@remotemachine 'cd repos_path && git merge laptop-master'
Rich
@rdoubleui para automatizar la fusión, puede usar gitolite y configurarlo (un poco complicado) para que lo no desnudo confirme todo sucio y lo empuje a la versión gitolite (desnuda) usando el disparador pre-git. Después de eso, si la fusión no se puede resolver de manera no visible, rechazará su empuje, por lo que sabe que tiene que tirar primero, resolver las fusiones y presionar nuevamente. Todavía no he configurado esto, pero estoy en el proceso y creo que puede funcionar.
17

Sugeriría tener un repositorio desnudo y repositorios locales de trabajo (no desnudos) en su servidor. Puede impulsar los cambios desde el repositorio desnudo de la computadora portátil al servidor y luego pasar de ese repositorio desnudo al repositorio de trabajo del servidor. La razón por la que digo esto es porque puede tener muchas ramas completas / incompletas en el servidor que querrá replicar en la computadora portátil.

De esta manera, no tiene que preocuparse por el estado de la sucursal verificada en el repositorio de trabajo del servidor mientras empuja los cambios al servidor.

Manish
fuente
4

Otra opción es configurar un túnel ssh inverso para que pueda tirar en lugar de empujar.

# start the tunnel from the natted box you wish to pull from (local)
$ ssh -R 1234:localhost:22 user@remote

# on the other box (remote)
$ git remote add other-side ssh://user@localhost:1234/the/repo
$ git pull other-side

Y si quieres que el túnel se ejecute en segundo plano

$ ssh -fNnR 1234:localhost:22 user@remote
Todd liberado
fuente
1

Tu puedes hacer:

$git config --bool core.bare true

Esto se puede hacer en un repositorio central o vacío para que acepte cualquier archivo que se envíe desde repositorios no vacíos. Si hace esto en un repositorio no desnudo, entonces no podemos enviar ningún archivo del repositorio no desnudo al repositorio.

Si está practicando GIT creando un repositorio central y no desnudo en la PC, es posible que no muestre los archivos enviados en algunas PC, pero se ha enviado. puedes verificarlo corriendo.

$git log en repo central.

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

vidwan reddy
fuente