¿Cómo se usa el repositorio "git --bare init"?

321

Necesito crear un repositorio central de Git pero estoy un poco confundido ...

He creado un repositorio simple (en mi servidor git, máquina 2) con:

$ mkdir test_repo
$ git --bare init

Ahora necesito enviar archivos desde mi repositorio local (máquina 1) al repositorio desnudo (máquina 2). Tengo acceso a la máquina 2 por SSH. La cuestión es que creo que no entiendo el concepto de un repositorio desnudo ...

¿Cuál es la forma correcta de almacenar mi código en el repositorio simple? ¿Cómo puedo enviar los cambios desde mi repositorio local al repositorio simple?

¿Es la forma correcta de tener un repositorio central para tener un repositorio desnudo?

Estoy un poco confundido con este tema. Por favor, dame una pista sobre esto.

André
fuente

Respuestas:

392

En primer lugar, solo para verificar, debe cambiar al directorio que ha creado antes de ejecutarlo git init --bare. Además, es convencional dar a los repositorios desnudos la extensión .git. Entonces puedes hacer

git init --bare test_repo.git

Para las versiones de Git <1.8 lo haría

mkdir test_repo.git
cd test_repo.git
git --bare init

Para responder a sus preguntas posteriores, los repositorios desnudos (por definición) no tienen un árbol de trabajo adjunto, por lo que no puede agregarles archivos fácilmente como lo haría en un repositorio no desnudo normal (por ejemplo, con git add <file>y un subsiguiente git commit. )

Casi siempre actualiza un repositorio desnudo presionándolo (usando git push) desde otro repositorio.

Tenga en cuenta que, en este caso, primero deberá permitir que las personas ingresen a su repositorio. Cuando adentro test_repo.git, haz

git config receive.denyCurrentBranch ignore

Edición comunitaria

git init --bare --shared=group

Como comentó prasanthv, esto es lo que desea si está haciendo esto en el trabajo, en lugar de para un proyecto de hogar privado.

Mark Longair
fuente
77
También puede agregar la --sharedopción initsi planea hacer que otras personas presionen para este repositorio. Agrega automáticamente permisos de escritura grupal al repositorio - enlace
prasanthv
17
Creo que estas tres líneas tienen el mismo efecto que esta única: git --bare init test_repo.git Al menos con mi versión actual de git (1.8.2.2)
Fran Marzoa
1
útil si quieres saber la diferencia entre repos desnudos y no descubiertos stackoverflow.com/questions/7861184/…
Guille Acosta
¿Cómo encuentra Git cosas si no hay un árbol que funcione? Me pareció que es un árbol de trabajo en el almacén de objetos git, y eso es lo que los agentes de mantenimiento de estadificación apuntan y se compromete a punto
akantoword
@akantoword: git almacena toda la información sobre commits y ramas en alguna parte. Una confirmación es probablemente una diferencia entre la versión anterior de los archivos y la nueva versión. El árbol de trabajo es solo una instantánea de su contenido real en un momento específico. De todos modos, con un árbol de trabajo puede ir y venir entre commits y ramas. Incluso puede pagar en un árbol de trabajo diferente si lo desea.
user276648
246

Estoy agregando esta respuesta porque después de llegar aquí (con la misma pregunta), ninguna de las respuestas realmente describe todos los pasos necesarios para pasar de la nada a un repositorio remoto (desnudo) totalmente utilizable.

Nota: este ejemplo utiliza rutas locales para la ubicación del repositorio simple, pero otros protocolos git (como SSH indicado por el OP) deberían funcionar bien.

Intenté agregar algunas notas en el camino para aquellos menos familiarizados con git.

1. Inicialice el repositorio desnudo ...

> git init --bare /path/to/bare/repo.git
Initialised empty Git repository in /path/to/bare/repo.git/

Esto crea una carpeta (repo.git) y la llena con archivos git que representan un repositorio git. Tal como está, este repositorio es inútil: no tiene compromisos y, lo que es más importante, no tiene ramas . Aunque puede clonar este repositorio, no puede extraerlo.

A continuación, necesitamos crear una carpeta de trabajo. Hay un par de formas de hacerlo, dependiendo de si tiene archivos existentes.

2a. Cree una nueva carpeta de trabajo (sin archivos existentes) clonando el repositorio vacío

git clone /path/to/bare/repo.git /path/to/work
Cloning into '/path/to/work'...
warning: You appear to have cloned an empty repository.
done.

Este comando solo funcionará si /path/to/workno existe o si es una carpeta vacía. Tome nota de la advertencia: en esta etapa, todavía no tiene nada útil. Si usted cd /path/to/worky corre git status, obtendrá algo como:

On branch master

Initial commit

nothing to commit (create/copy files and use "git add" to track)

Pero esto es una mentira. Realmente no estás en la rama master(porque git branchno devuelve nada) y hasta ahora, no hay confirmaciones.

A continuación, copie / mueva / cree algunos archivos en la carpeta de trabajo, agréguelos a git y cree la primera confirmación.

> cd /path/to/work
> echo 123 > afile.txt
> git add .
> git config --local user.name adelphus
> git config --local user.email [email protected]
> git commit -m "added afile"
[master (root-commit) 614ab02] added afile
 1 file changed, 1 insertion(+)
 create mode 100644 afile.txt

Los git configcomandos solo son necesarios si aún no le has dicho a git quién eres. Tenga en cuenta que si ahora ejecuta git branch, ahora verá la masterrama en la lista. Ahora ejecuta git status:

On branch master
Your branch is based on 'origin/master', but the upstream is gone.
  (use "git branch --unset-upstream" to fixup)

nothing to commit, working directory clean

Esto también es engañoso: el flujo ascendente no se ha "ido", simplemente no se ha creado todavía y git branch --unset-upstreamno ayudará. Pero está bien, ahora que tenemos nuestro primer commit, podemos presionar y se creará master en el repositorio simple.

> git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 207 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /path/to/bare/repo.git
 * [new branch]      master -> master

En este punto, tenemos un repositorio desnudo completamente funcional que se puede clonar en otro lugar en una rama maestra, así como una copia de trabajo local que puede extraer y empujar.

> git pull
Already up-to-date.
> git push origin master
Everything up-to-date

2b. Crear una carpeta de trabajo a partir de archivos existentes Si ya tiene una carpeta con archivos (por lo que no puede clonar en ella), puede inicializar un nuevo repositorio git, agregar un primer commit y luego vincularlo al repositorio desnudo después.

> cd /path/to/work_with_stuff
> git init 
Initialised empty Git repository in /path/to/work_with_stuff
> git add .
# add git config stuff if needed
> git commit -m "added stuff"

[master (root-commit) 614ab02] added stuff
 20 files changed, 1431 insertions(+)
 create mode 100644 stuff.txt
...

En este punto tenemos nuestro primer commit y una rama maestra local que necesitamos convertir en una rama ascendente de seguimiento remoto.

> git remote add origin /path/to/bare/repo.git
> git push -u origin master
Counting objects: 31, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (31/31), done.
Writing objects: 100% (31/31), 43.23 KiB | 0 bytes/s, done.
Total 31 (delta 11), reused 0 (delta 0)
To /path/to/bare/repo.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

Observe la -ubandera en git push para establecer la (nueva) rama ascendente rastreada. Al igual que antes, ahora tenemos un repositorio desnudo completamente funcional que se puede clonar en otro lugar en una rama maestra, así como una copia de trabajo local que puede extraer y empujar.

Todo esto puede parecer obvio para algunos, pero git me confunde en el mejor de los casos (sus mensajes de error y estado realmente necesitan un poco de revisión); con suerte, esto ayudará a otros.

adelphus
fuente
44
Interesante. Ciertamente más detallado que mi respuesta. +1
VonC
13
Esta respuesta resuelve mi problema y debería ser la respuesta aceptada, espero que más y más personas puedan votarla.
inix
11
Debería cobrar dinero por respuestas como esta
Arthur Tarasov el
2
Como nuevo usuario de git, esta respuesta fue increíblemente útil para mí, ¡gracias por escribir esto!
sidewinderguy
1
Esta es una respuesta brillante. Ayudará mucho a nuestra unidad.
wobsoriano
33

Responde tus preguntas una por una:

El repositorio desnudo es el que no tiene árbol de trabajo . Significa que todo su contenido es lo que tiene en el .gitdirectorio.

Solo puede commitmostrar el repositorio pushdesde su clon local. No tiene árbol de trabajo, por lo que no tiene archivos modificados, ni cambios.

Para tener un repositorio central, la única forma es tener un barerepositorio.

Marcin Gil
fuente
22

También puede pedirle a git que cree un directorio para usted:

git init --bare test_repo.git
Serge S.
fuente
20

La práctica general es tener el repositorio central al que empuje como un repositorio simple.

Si tiene antecedentes SVN, puede relacionar un repositorio SVN con un repositorio desnudo de Git. No tiene los archivos en el repositorio en la forma original. Mientras que su repositorio local tendrá los archivos que forman su "código" además.

Debe agregar un control remoto al repositorio simple desde su repositorio local y enviarle su "código".

Será algo como:

git remote add central <url> # url will be ssh based for you
git push --all central
manojlds
fuente
Usando git remote add central <url>, en el caso de SSH, ¿esto también incluiría la ruta? Por ejemplogit remote add central ssh://user@server/home/user/repo.git
Sí, Barry, el
17

Esto debería ser suficiente:

git remote add origin <url-of-bare-repo>
git push --all origin

Consulte para más detalles " GIT: ¿Cómo actualizo mi repositorio simple? ".
Notas:

  • puede usar un nombre diferente a ' origin' para la referencia remota de repositorio simple.
  • esto no empujará sus etiquetas, necesita un separado git push --tags originpara eso.
VonC
fuente
5

Es bueno verificar que el código que presionó realmente se confirmó.

Puede obtener un registro de los cambios en un repositorio desnudo configurando explícitamente la ruta utilizando la opción --relative.

$ cd test_repo
$ git log --relative=/

Esto le mostrará los cambios confirmados como si fuera un repositorio git regular.

Russell
fuente
5

Según las respuestas de Mark Longair y Roboprog:

si la versión git> = 1.8

git init --bare --shared=group .git
git config receive.denyCurrentBranch ignore

O:

si la versión git <1.8

mkdir .git
cd .git
git init --bare --shared=group 
git config receive.denyCurrentBranch ignore
Jack'
fuente
Ese comando de configuración: ¿cómo termina aplicándose al directorio .git que acaba de crear?
GreenAsJade
¿No estoy seguro de entender tu pregunta? Puedes ser mas preciso ? Como tiene su repositorio git inicializado, puede configurarlo todo lo que quiera con el comando 'git config' ..
Jack
@GreenAsJade Es porque todavía estás dentro de la carpeta del repositorio de git, por lo que se aplica a eso (el valor predeterminado de la configuración de git es como la opción --local).
BlueCoder
2

El indicador --bare crea un repositorio que no tiene un directorio de trabajo. El repositorio básico es el repositorio central y no puede editar (almacenar) códigos aquí para evitar el error de fusión.

Por ejemplo, cuando agrega un archivo en su repositorio local (máquina 1) y lo empuja al repositorio desnudo, no puede ver el archivo en el repositorio desnudo porque siempre está 'vacío'. Sin embargo, realmente empuja algo al repositorio y puede verlo de manera inexplicable clonando otro repositorio en su servidor (máquina 2).

Tanto el repositorio local en la máquina 1 como el repositorio de 'copia' en la máquina 2 no están desnudos. relación entre repositorios desnudos y no desnudos

El blog te ayudará a entenderlo. https://www.atlassian.com/git/tutorials/setting-up-a-repository

Jie Zhang
fuente
0

Puede ejecutar los siguientes comandos para inicializar su repositorio local

mkdir newProject
cd newProject
touch .gitignore
git init
git add .
git commit -m "Initial Commit"
git remote add origin user@host:~/path_on_server/newProject.git
git push origin master

Debe trabajar en su proyecto desde su repositorio local y utilizar el servidor como repositorio central.

También puede seguir este artículo que explica todos y cada uno de los aspectos de la creación y el mantenimiento de un repositorio Git. Git para principiantes

Sameer Ranjan
fuente