¿Cuál es la diferencia entre "git init" y "git init --bare"?

162

¿Cuál es la diferencia entre git inity git init --bare? ¿Encontré que muchas publicaciones de blog requieren --barepara su servidor Git?

Desde la página del manual , decía:

--bare

Crea un repositorio desnudo. Si no se establece el entorno GIT_DIR, se establece en el directorio de trabajo actual

Pero, ¿qué significa realmente? ¿Es necesario tener --barepara la configuración del servidor Git?

Kit Ho
fuente

Respuestas:

143

Repo de Git no desnudo

Esta variante crea un repositorio con un directorio de trabajo para que realmente pueda trabajar ( git clone). Después de crearlo, verá que el directorio contiene una carpeta .git donde va el historial y toda la fontanería git. Trabajas en el nivel donde está la carpeta .git.

Bare Git Repo

La otra variante crea un repositorio sin un directorio de trabajo ( git clone --bare). No obtienes un directorio donde puedas trabajar. Todo en el directorio ahora es lo que estaba contenido en la carpeta .git en el caso anterior.

¿Por qué usarías uno contra el otro?

La necesidad de repositorios git sin un directorio de trabajo es el hecho de que puede empujar ramas hacia él y no administra lo que alguien está trabajando. Todavía puede empujar a un repositorio que no esté vacío, pero será rechazado ya que potencialmente puede mover una rama en la que alguien está trabajando en ese directorio de trabajo.

Entonces, en un proyecto sin carpeta de trabajo, solo puede ver los objetos a medida que git los almacena. Se comprimen y se serializan y se almacenan bajo el SHA1 (un hash) de sus contenidos. Para obtener un objeto en un repositorio simple, necesita git showy luego especificar el sha1 del objeto que desea ver. No verá una estructura como la de su proyecto.

Los repositorios desnudos suelen ser repositorios centrales donde todos mueven su trabajo. No hay necesidad de manipular el trabajo real. Es una forma de sincronizar esfuerzos entre varias personas. No podrá ver directamente los archivos de su proyecto.

Es posible que no tenga necesidad de repositorios desnudos si es el único que trabaja en el proyecto o si no desea / necesita un repositorio "lógicamente central". Uno preferiría git pull de los otros repositorios en ese caso. Esto evita las objeciones que tiene git cuando se empuja a repositorios no descubiertos.

Espero que esto ayude

Adam Dymitruk
fuente
Mantener el , tirar un de esta línea - Uno preferiría git pull del otro ... :-)
Arup Rakshit
10
Encuentro esta respuesta muy poco clara y confusa. Algunas de las razones están aquí: meta.stackoverflow.com/questions/339837/…
Marko Avlijaš
Bare repositories are usually central repositories where everyone moves their work to.¿Quiere decir que un repositorio simple es la fuente desde la cual otros colaboradores del proyecto pueden clonar un proyecto? Es decir, los colaboradores tratan esto como el remote?
Minh Tran
112

Respuesta corta

Un repositorio simple es un repositorio git sin una copia de trabajo, por lo tanto, el contenido de .git es de nivel superior para ese directorio.

Use un repositorio no desnudo para trabajar localmente y un repositorio desnudo como servidor / concentrador central para compartir sus cambios con otras personas. Por ejemplo, cuando crea un repositorio en github.com, se crea como un repositorio simple.

Entonces, en tu computadora:

git init
touch README
git add README
git commit -m "initial commit"

en el servidor:

cd /srv/git/project
git init --bare

Luego, en el cliente, empuja:

git push username@server:/srv/git/project master

Luego puede ahorrarse la escritura agregándola como control remoto.

El repositorio en el lado del servidor obtendrá confirmaciones mediante extracción y empuje, y no editando archivos y luego confirmándolos en la máquina del servidor, por lo tanto, es un repositorio desnudo.

Detalles

Puede pasar a un repositorio que no sea un repositorio simple, y git descubrirá que hay un repositorio .git allí, pero como la mayoría de los repositorios "hub" no necesitan una copia de trabajo, es normal usar un repositorio simple para y recomendado ya que no tiene sentido tener una copia de trabajo en este tipo de repositorios.

Sin embargo, si empuja a un repositorio no desnudo, está haciendo que la copia de trabajo sea inconsistente, y git le advertirá:

remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.

Puedes saltarte esta advertencia. Pero la configuración recomendada es: use un repositorio no desnudo para trabajar localmente y un repositorio desnudo como un concentrador o servidor central para empujar y extraer.

Si desea compartir el trabajo directamente con la copia de trabajo de otro desarrollador, puede extraer los depósitos de cada uno en lugar de presionar.

Duncan
fuente
si quiero trabajar mi proyecto en el servidor git, entonces no es necesario tener la opción --bare, ¿no es así?
Kit Ho
Utiliza bare para el repositorio remoto, no para el local.
Duncan
Es un momento, pero aquí hay otra pregunta. Si tenemos un repositorio remoto desnudo, cualquier desarrollador puede empujarlo, y el repositorio es uno "central". Pero si trabajamos sin un repositorio simple, los desarrolladores solo deberían separarse unos de otros, pero nunca presionar. El último escenario es bueno, si solo hay 2 copias de trabajo del repositorio (también conocido como repositorios locales). ¿Es esto correcto?
Asturio
60

Cuando leí esta pregunta hace algún tiempo, todo me resultaba confuso. Acabo de comenzar a usar git y hay estas copias de trabajo (que no significaban nada en ese momento). Trataré de explicar esto desde la perspectiva del chico, que acaba de comenzar git sin tener idea de la terminología.

Un buen ejemplo de las diferencias se puede describir de la siguiente manera :

--barete da solo un lugar de almacenamiento (no puedes desarrollar allí). Sin --bareella, te da la capacidad de desarrollarte allí (y tener un lugar de almacenamiento).

git initcrea un repositorio git desde su directorio actual. Agrega la carpeta .git dentro de él y hace posible comenzar su historial de revisiones.

git init --bareTambién crea un repositorio, pero no tiene el directorio de trabajo. Esto significa que no puede editar archivos, confirmar sus cambios, agregar nuevos archivos en ese repositorio.

¿Cuándo --barepuede ser útil? Usted y algunos otros muchachos están trabajando en el proyecto y usan git. Has alojado el proyecto en algún servidor ( amazon ec2). Cada uno de ustedes tiene su propia máquina y activa su código ec2. Ninguno de ustedes desarrolla nada en realidad ec2(usa sus máquinas), simplemente empuja su código. Por lo tanto, ec2es solo un almacenamiento para todo su código y debe crearse como --barey todas sus máquinas sin --bare(lo más probable es que solo una, y otra simplemente clone todo). El flujo de trabajo se ve así:

ingrese la descripción de la imagen aquí

Salvador Dalí
fuente
1
Entonces, podríamos decir que al usar un repositorio --bare podemos crear una especie de arquitectura cliente-servidor como lo hace la subversión.
Emiliano Sangoi
14

Un repositorio Git predeterminado asume que lo usará como su directorio de trabajo. Normalmente, cuando está en un servidor, no necesita tener un directorio de trabajo. Solo el repositorio. En este caso, debes usar la --bareopción.

Sandro Munda
fuente
en un repositorio con la opción --bare, por lo que no podemos ver todo el archivo del proyecto? Parece que pierdo todo mi archivo de proyecto con la opción --bare ..
Kit Ho
11

Un repositorio no desnudo es el predeterminado. Es lo que se crea cuando ejecuta git inito lo que obtiene cuando clona (sin la bareopción) desde un servidor.

Cuando trabaja con un repositorio como este, puede ver y editar todos los archivos que están en el repositorio. Cuando interactúa con el repositorio, por ejemplo, al confirmar un cambio, Git almacena sus cambios en un directorio oculto llamado .git.

Cuando tienes un servidor git no hay necesidad de que haya copias de trabajo de los archivos. Todo lo que necesitas son los datos de Git que están almacenados .git. Un repositorio simple es exactamente el .gitdirectorio, sin un área de trabajo para modificar y confirmar archivos.

Cuando clonas desde un servidor, Git tiene toda la información que necesita en el .gitdirectorio para crear tu copia de trabajo.

Andrés
fuente
1

Otra diferencia entre los repositorios --bare y Working Tree es que, en el primer caso, no se almacenan confirmaciones perdidas, sino que solo se almacenan las confirmaciones que pertenecen a una pista de bifurcación . Por otro lado, Working Tree mantiene todas las confirmaciones para siempre. Vea abajo...

Creé el primer repositorio (nombre: git-bare ) con git init --bare. Es el servidor. Está en el lado izquierdo, donde no hay ramas remotas porque este es el repositorio remoto en sí.

Creé el segundo repositorio (nombre: git-working-tree ) con git cloneel primero. Está a la derecha. Tiene sucursales locales vinculadas a sucursales remotas.

(Los textos 'primero', 'segundo', 'tercero', 'cuarto', 'alfa', 'beta' y 'delta' son los comentarios de confirmación. Los nombres 'maestro' y 'griego' son nombres de rama.)

Repositorios locales y remotos

Ahora eliminaré la rama llamada 'griego' tanto en git-bare (command git push --delete origin greek:) como localmente en git-working-tree (command:) git branch -D greek. Así es como se ve el árbol:

El repositorio git-bare elimina lo que ya no se hace referencia

El repositorio git-bare elimina tanto la rama como todos los comits referenciados. En la imagen vemos que su árbol se redujo por este motivo.

Por otro lado, el repositorio git-working-tree , que es equivalente a un repositorio local de uso común, no elimina las confirmaciones, que ahora solo pueden ser referenciadas directamente por su hash con un git checkout 7fa897b7comando. Es por eso que su árbol no tiene su estructura modificada.

BREVES: Las confirmaciones nunca se eliminan en los repositorios del árbol de trabajo , sino que se eliminan en los repositorios desnudos .

En términos prácticos, solo puede recuperar una rama eliminada en el servidor si existe en un repositorio local.

Pero es muy raro que el tamaño del desnudo repositorio no disminuye en tamaño del disco después de borrar una rama remota. Es decir, los archivos todavía están allí de alguna manera. Para volcar el repositorio eliminando lo que ya no se hace referencia o lo que nunca se puede hacer referencia (este último caso) use el git gc --prunecomando

Sergio Cabral
fuente
Para probar los comandos de git, intente: github.com/sergiocabral/App.GitPlayground
Sergio Cabral