Usando git como repositorio central

12

He configurado git para mi propio uso, por lo que puedo acceder a un proyecto desde 'cualquier lugar' y mantener la seguridad de la versión si estoy trabajando en la parte X aquí y en la parte Y aquí, y puedo fusionarme si es necesario.

Sin embargo, solo una de mis máquinas de desarrollo tiene una IP estática. Mi cerebro está atascado en el modo CVS, así que intenté configurar git para que esa máquina sea el servidor 'central', del que todos los demás se extraen.

Este tipo de trabajos. Tengo un montón de máquinas AC que hacen un git-pull del "maestro" M. Hacen git push para enviar los datos de vuelta.

El problema viene si hago desarrollo en el maestro. Primero, no puedo entender cómo hacer que el repositorio central proporcione la última versión sin hacerlo

git reset --hard HEAD

lo que parece un poco excesivo Y si desarrollo en la máquina central antes de reiniciar, no estoy seguro de cómo fusionarlo con los cambios que ya se han presionado.

Algo sobre mi modelo mental está muy lejos. ¿Ayuda?

Alex Feinman
fuente
Cuando dices "maestro", ¿estás hablando del repositorio maestro o de la rama maestra?
innaM
repositorio principal
Alex Feinman
1
"maestro" en el contexto de git suele ser el nombre de la rama predeterminada.
innaM
esto probablemente pertenece a SO
Ken Liu

Respuestas:

30

Desea que su repositorio central esté vacío. Digamos que la máquina en la que vive se llama static:

$ ssh static git init --bare /git/myproject.git

Este repositorio básico es un punto de encuentro central: es para empujar hacia y desde, no para el desarrollo.

Realice su desarrollo en clones del repositorio central:

$ cd ~/src
$ git clone static:/git/myproject.git

Incluso si estás statictrabajando, trabaja en un clon:

$ git clone /git/myproject.git

Aunque eres el único que trabaja en este repositorio, adquiere el hábito de hacer tu trabajo en lo que la documentación de git llama ramas temáticas . Un beneficio inmediato de esto es que mantiene un maestro limpio , es decir, siempre puede extraerlo de su rama maestra central en el maestro de su repositorio local actual sin fusión.

Por ejemplo:

$ git checkout -b fix-bug-in-foo
$ hack
$ git add file.c file.h
$ git commit -m "Fix ..."

Puede que no parezca un gran problema, pero le da la libertad de dejar el proyecto como se representa en esa rama en un estado parcialmente cocido, o si su idea genial resulta ser un fracaso, puede tirar fácilmente esa rama sin rompiendo cualquier otra cosa en su proyecto que ya esté trabajando en otras ramas. ¡Infinitos mulligans gratis!

Tal vez te vayas a casa esa noche y agregues una nueva característica. A la mañana siguiente, tú

$ git checkout master
$ git pull

para actualizar su maestro local para reflejar lo que hay en el repositorio central.

Pero ahora digamos que ha solucionado el error foo y está listo para incluirlo en su rama maestra. Primero quieres integrarlo con los cambios de anoche:

$ git checkout fix-bug-in-foo
$ git rebase master

El rebasecomando hace que su repositorio parezca que solucionó el error foo además de la nueva característica de la noche anterior. (Esto es algo así como svn update, pero más flexible y poderoso).

Ahora para llevarlo a su maestro central:

$ git checkout master
$ git merge fix-bug-in-foo
$ git push origin master

Hemos tratado al maestro como especial, pero eso es solo convencional. Puede compartir el trabajo en diferentes ramas de diferentes repositorios a través del repositorio git con la staticmisma facilidad.

Greg Bacon
fuente
1
Impresionante respuesta, aclara todos los problemas a la mano.
Dan Loewenherz
Mi instalación de git no acepta --bare como una opción para git init (versión anterior ??), pero lo solucioné clonando --bare mi repositorio existente y luego edito un poco manualmente los archivos de configuración.
Alex Feinman
Si está ejecutando git 1.6.4.x, no git init --baretiene otros argumentos. Utilizará el directorio de trabajo actual o la configuración del entorno GIT_DIR si está configurado. Creo que necesita git 1.6.5.x para que tome un argumento de directorio.
Darren Hall
44
Esa es la mejor explicación de flujo de trabajo de git que he visto hasta ahora para el trabajo que estoy haciendo.
Greg Graham
8

Si tiene un servidor central con un repositorio central de git, ese repositorio debe ser un barerepositorio. Los repositorios desnudos no tienen copias de trabajo de los archivos en ellos. En consecuencia, si está trabajando en esa máquina central, no trabaja directamente con el repositorio central, sino con un clon local.

innaM
fuente
6

Esta respuesta es similar a la respuesta de gbacon , pero adopta el enfoque de que ya tiene una configuración de repositorio local y desea crear un maestro remoto que se trate como un repositorio central. Solo está agregando detalles desde un enfoque diferente.

Yo uso git para almacenar mis archivos dot-config. Empujo y tiro de lo que considero un "repositorio central". Es bastante conveniente restablecer todos mis archivos de puntos a través de múltiples computadoras.

$ ssh example.com
$ mkdir dotconf.git && cd dotconf.git
$ git init --bare
$ exit

Esto creó un repositorio vacío en el sitio del repositorio.

Ahora, si ya tengo un repositorio local, puedo enviarlo al sitio remoto.

$ cd ~/src/dotconf

chdir en el directorio local.

$ git remote add origin ssh://example.com/~/dotconf.git

Agregue el repositorio remoto como el origen, por lo que push / pull actuará sobre ese repositorio.

$ git push origin master

Empuje mi maestro al origen (como se etiquetó anteriormente a través del control remoto git). Ahora ese repositorio remoto se trata como mi 'repositorio central'. Todos mis git push / pull interactuarán con el origen.

Si voy a otro host, puedo extraer fácilmente a través de clones que reposicionan a una nueva ubicación.

$ git clone ssh://example.com/~/dotconf.git

Si quiero desarrollar en el servidor remoto, primero clono, luego empujo / retrocedo al repositorio desnudo.

$ cd ~/src
$ git clone ~/dotconf.git
$ cd ~/src/dotconf
  * do coding *
$ git push
  * check in from another location *
$ git pull

Es probable que tengas que configurarlo, git config --add branch.master.remote originasí que git pullno te quejes de que no estás siendo lo suficientemente específico. La otra alternativa es establecer su rama maestra en --trackel origen remoto. Útil si tienes varias ramas.

Darren Hall
fuente
1

Estaba investigando este mismo problema hoy. Este blog posterior tiene una gran cantidad de discusión sobre el tema, pero la opinión mayoritaria es hacer lo que dijo Manni. Mire un comentario en la publicación de David French para conocer otras posibilidades, incluido qué hacer si termina empujando por error a un repositorio que tiene trabajo no comprometido en el índice o el árbol de trabajo. "git reset –soft HEAD ^" retrocederá el cambio empujado sin perturbar su trabajo.

Greg Graham
fuente
2
Un problema con esa publicación de blog es omitir la utilidad del índice. Aquí hay un buen artículo para explicar cómo trabajar con git en lugar de a pesar de git - osteele.com/archives/2008/05/my-git-workflow - se incluyen diagramas de flujo de trabajo.
Darren Hall