¿Cuál es la diferencia práctica entre un repositorio desnudo y no desnudo?

213

He estado leyendo sobre los repositores desnudos y no desnudos / predeterminados en Git. No he podido entender muy bien (teóricamente) sobre las diferencias entre ellos y por qué debería "empujar" a un repositorio simple. Aquí está el trato:

Actualmente, soy el único que trabaja en un proyecto en 3 computadoras diferentes, pero habrá más personas involucradas más adelante, así que estoy usando Git para el control de versiones. Clono el repositorio simple en todas las computadoras, y cuando termino mis modificaciones en una de ellas, me comprometo y empujo los cambios al repositorio simple. Por lo que he leído, el repositorio simple NO tiene un "árbol de trabajo", así que si clono el repositorio simple, no tendré un "árbol de trabajo".

Supongo que el árbol de trabajo almacena la información de confirmación, ramas, etc. del proyecto. Eso no aparecería en el repositorio desnudo. Por lo tanto, me parece mejor "empujar" los compromisos al repositorio con el árbol de trabajo.

Entonces, ¿por qué debería usar el repositorio simple y por qué no? ¿Cuál es la diferencia práctica? Supongo que eso no sería beneficioso para más personas que trabajan en un proyecto.

¿Cuáles son sus métodos para este tipo de trabajo? Sugerencias?

AeroCross
fuente
44
AeroCross, puede clonar un repositorio desnudo para crear un repositorio no desnudo (es decir, uno que tenga un espacio de trabajo). Por lo tanto, el uso git clonepuede convertir libremente entre repositorios desnudos y no desnudos.
Derek Mahar
13
@AeroCross: No se trata de convertir; No importa lo que esté al otro lado. Si corres git clone --bare, obtendrás un repositorio desnudo, y si corres git clone, obtendrás uno no desnudo. Cada proyecto público que alguna vez haya clonado (alojado en github, por ejemplo) es un repositorio desnudo en el otro extremo.
Cascabel
1
Jefromi, estaba corrigiendo el punto de AeroCross, "así que si clono el repositorio desnudo, no tendré un" árbol de trabajo "", así que es una especie de conversión. Y no todos los proyectos públicos deben ser un repositorio desnudo. Es la opción típica porque un repositorio simple es más eficiente en cuanto al espacio ya que no tiene un árbol de trabajo (sin embargo, es tan eficiente en el espacio como cualquier repositorio que no tenga un árbol de trabajo).
Derek Mahar
2
@Derek: Pero el punto es que, tan pronto como encuentra el directorio .git, la búsqueda no es totalmente consciente de si el control remoto está vacío o no. No se convierte. Simplemente obtiene lo que necesita del control remoto y lo coloca donde debería ir. No hay nada para convertir. Eso es lo que estaba tratando de enfatizar en el OP. Y soy muy consciente de que los proyectos públicos no tienen que ser simples, pero debido a que las personas no son estúpidas, en esencia lo son todas. Creo que hice una generalización aceptable.
Cascabel
2
Consulte Push to no-bare repositorio que ofrece otra excelente explicación del uso del repositorio desnudo.
Craig McQueen

Respuestas:

95

Otra diferencia entre un repositorio desnudo y no desnudo es que un repositorio desnudo no tiene un repositorio de origen remoto predeterminado :

~/Projects$ git clone --bare test bare
Initialized empty Git repository in /home/derek/Projects/bare/
~/Projects$ cd bare
~/Projects/bare$ git branch -a
* master
~/Projects/bare$ cd ..
~/Projects$ git clone test non-bare
Initialized empty Git repository in /home/derek/Projects/non-bare/.git/
~/Projects$ cd non-bare
~/Projects/non-bare$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

Desde la página del manual para git clone --bare:

Además, los cabezales de sucursal en el control remoto se copian directamente a los jefes de sucursal locales correspondientes, sin asignarlos a refs / remotes / origin /. Cuando se utiliza esta opción, no se crean ramas de seguimiento remoto ni las variables de configuración relacionadas.

Presumiblemente, cuando crea un repositorio desnudo, Git asume que el repositorio desnudo servirá como el repositorio de origen para varios usuarios remotos, por lo que no crea el origen remoto predeterminado. Lo que esto significa es que las operaciones básicas git pully git pushno funcionarán, ya que Git asume que sin un espacio de trabajo, no tiene la intención de confirmar ningún cambio en el repositorio simple:

~/Projects/bare$ git push
fatal: No destination configured to push to.
~/Projects/bare$ git pull
fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.
~/Projects/bare$ 
Derek Mahar
fuente
1
Sí, estoy de acuerdo en que esta es posiblemente la diferencia más significativa entre los repositorios Git desnudos y no desnudos. El hecho de que un repositorio no desnudo tenga un espacio de trabajo, pero un repositorio desnudo no es una diferencia importante, pero también git clone --no-checkoutpuede crear un repositorio no desnudo sin archivos del espacio de trabajo.
Derek Mahar
10
Un repositorio no desnudo tampoco tiene necesariamente un "origen" remoto predeterminado.
mipadi
2
Puede crear un repositorio de Git simplemente con git init, que creará un repositorio no desnudo sin especificación remota.
mipadi
1
mipadi, esto es cierto, pero tampoco es un clon.
Derek Mahar
1
Esto es incorrecto. Un repositorio tendrá un origen predeterminado si se ha cloneeditado. Si se ha initeditado localmente, no tendrá dicho origen. Esto no tiene nada que ver con si está desnudo o no.
Noufal Ibrahim
62

La distinción entre un repositorio Git desnudo y no desnudo es artificial y engañosa ya que un espacio de trabajo no es parte del repositorio y un repositorio no requiere un espacio de trabajo. Estrictamente hablando, un repositorio de Git incluye aquellos objetos que describen el estado del repositorio. Estos objetos pueden existir en cualquier directorio, pero generalmente existen en el .gitdirectorio en el directorio de nivel superior del espacio de trabajo. El espacio de trabajo es un árbol de directorios que representa una confirmación particular en el repositorio, pero puede existir en cualquier directorio o no existir. La variable de entorno $GIT_DIRvincula un espacio de trabajo al repositorio desde el que se origina.

Los comandos de Git git cloney git initambos tienen opciones --bareque crean repositorios sin un espacio de trabajo inicial. Es desafortunado que Git combine los dos conceptos separados, pero relacionados de espacio de trabajo y repositorio, y luego use el término confuso desnudo para separar las dos ideas.

Derek Mahar
fuente
61

Un repositorio desnudo no es más que la carpeta .git en sí misma, es decir, el contenido de un repositorio desnudo es el mismo que el contenido de la carpeta .git dentro de su repositorio de trabajo local.

  • Use el repositorio simple en un servidor remoto para permitir que múltiples contribuyentes impulsen su trabajo.
  • No desnudo: el que tiene un árbol de trabajo tiene sentido en la máquina local de cada contribuyente de su proyecto.
Deepak Sharma
fuente
60

5 años demasiado tarde, lo sé, pero en realidad nadie respondió la pregunta:

Entonces, ¿por qué debería usar el repositorio simple y por qué no? ¿Cuál es la diferencia práctica? Supongo que eso no sería beneficioso para más personas que trabajan en un proyecto.

¿Cuáles son sus métodos para este tipo de trabajo? Sugerencias?

Para citar directamente del libro de Loeliger / MCullough (978-1-449-31638-9, p196 / 7):

Un repositorio desnudo puede parecer de poca utilidad, pero su papel es crucial: servir como un punto focal autorizado para el desarrollo colaborativo. Otros desarrolladores cloney fetchdesde el repositorio simple y pushactualizaciones a él ... si configura un repositorio en el que los desarrolladores pushcambian, debería estar vacío. En efecto, este es un caso especial de la mejor práctica más general que un repositorio publicado debe estar al descubierto.

EML
fuente
19

Un repositorio no desnudo simplemente tiene un árbol de trabajo desprotegido. El árbol de trabajo no almacena ninguna información sobre el estado del repositorio (ramas, etiquetas, etc.); más bien, el árbol de trabajo es solo una representación de los archivos reales en el repositorio, lo que le permite trabajar en (editar, etc.) los archivos.

mipadi
fuente
Entonces, ¿eso significa que puedo agregar ramas, etiquetas, etc. al repositorio desnudo y luego extraer del repositorio desnudo al repositorio de producción / no desnudo?
AeroCross
2
mipadi, un repositorio no descubierto puede no tener un árbol desprotegido. Este es el caso si crea un repositorio no desnudo con git clone --no-checkout. En este caso, el repositorio no desnudo tiene una ubicación para el espacio de trabajo, pero Git no desprotege ningún archivo en ese espacio de trabajo.
Derek Mahar
17

Un repositorio desnudo tiene beneficios en

  • uso reducido del disco
  • Menos problemas relacionados con el envío remoto (ya que no hay un árbol de trabajo para salir de la sincronización o tener cambios conflictivos)
sehe
fuente
3
¿Entonces el repositorio simple es la mejor / recomendada forma de trabajar con varias personas sin acceso a SUS repositorios? (¿Un poco como SVN?)
AeroCross
2
AeroCross, diría que un repositorio simple es una buena opción para ese escenario.
Derek Mahar
12

El repositorio no desnudo le permite (en su árbol de trabajo) capturar cambios creando nuevas confirmaciones.

Los repositorios desnudos solo cambian al transportar los cambios desde otros repositorios.

Nitina
fuente
10

Ciertamente no soy un "experto" de Git. He usado TortoiseGit durante un tiempo y me preguntaba de qué estaba hablando cuando me preguntaba si quería hacer un repositorio "desnudo" cada vez que creaba uno. Estaba leyendo este tutorial: https://www.atlassian.com/git/tutorials/setting-up-a-repository/git-init y aborda el problema, pero todavía no entendía bien el concepto. Esto ayudó mucho: http://bitflop.com/tutorials/git-bare-vs-non-bare-repositories.html . ¡Ahora, el primero también tiene sentido!

Según estas fuentes, en pocas palabras se utiliza un repositorio "desnudo" en un servidor donde desea configurar un punto de distribución. No está destinado para su uso en su máquina local. Por lo general, envía confirmaciones desde su máquina local a un repositorio descubierto en un servidor remoto, y usted y / u otros extraen de ese repositorio vacío a su máquina local. Por lo tanto, su repositorio de distribución / almacenamiento remoto de GitHub, Assembla, etc. es un ejemplo en el que se crea un repositorio "desnudo". Usted mismo haría uno si estuviera estableciendo su propio "centro de intercambio" análogo.

BuvinJ
fuente
ooooh ahora lo entiendo
Fuseteam
9

Un repositorio Git predeterminado / no desnudo contiene dos partes de estado:

  1. Una instantánea de todos los archivos en el repositorio (esto es lo que significa "árbol de trabajo" en la jerga de Git)
  2. Un historial de todos los cambios realizados en todos los archivos que han estado en el repositorio (no parece haber una pieza concisa de la jerga de Git que abarque todo esto)

La instantánea es lo que probablemente piense que es su proyecto: sus archivos de código, archivos de compilación, scripts de ayuda y cualquier otra cosa que versione con Git.

El historial es el estado que le permite verificar una confirmación diferente y obtener una instantánea completa de cómo se veían los archivos en su repositorio cuando se agregó esa confirmación. Consiste en un montón de estructuras de datos que son internas de Git con las que probablemente nunca has interactuado directamente. Es importante destacar que el historial no solo almacena metadatos (por ejemplo, "El usuario U agregó tantas líneas al archivo F en el tiempo T como parte de la confirmación C"), también almacena datos (por ejemplo, "el usuario U agregó estas líneas exactas al archivo F" )

La idea clave de un repositorio simple es que en realidad no es necesario tener la instantánea. Git mantiene la instantánea porque es conveniente para los humanos y otros procesos que no son de Git que desean interactuar con su código, pero la instantánea es solo un estado duplicado que ya está en la historia.

Un repositorio simple es un repositorio de Git que no tiene una instantánea. Simplemente almacena la historia.

Por qué querrías esto? Bueno, si solo va a interactuar con sus archivos usando Git (es decir, no va a editar sus archivos directamente o usarlos para construir un ejecutable), puede ahorrar espacio al no mantener la instantánea. En particular, si está manteniendo una versión centralizada de su repositorio en un servidor en algún lugar (es decir, básicamente está alojando su propio GitHub), ese servidor probablemente debería tener un repositorio desnudo (aún usaría un repositorio no desnudo en su máquina local, sin embargo, ya que presumiblemente querrá editar su instantánea).

Si desea una explicación más detallada de los repositorios desnudos y otro caso de uso de ejemplo, escribí una publicación de blog aquí: https://stegosaurusdormant.com/bare-git-repo/

Greg Owen
fuente
4

Esta no es una respuesta nueva, pero me ayudó a comprender los diferentes aspectos de las respuestas anteriores (y es demasiado para un comentario).

Usando Git Bash solo prueba:

me@pc MINGW64 /c/Test
$ ls -al
total 16
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../

me@pc MINGW64 /c/Test
$ git init
Initialized empty Git repository in C:/Test/.git/

me@pc MINGW64 /c/Test (master)
$ ls -al
total 20
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 .git/

me@pc MINGW64 /c/Test (master)
$ cd .git

me@pc MINGW64 /c/Test/.git (GIT_DIR!)
$ ls -al
total 15
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 ../
-rw-r--r-- 1 myid 1049089 130 Apr  1 11:35 config
-rw-r--r-- 1 myid 1049089  73 Apr  1 11:35 description
-rw-r--r-- 1 myid 1049089  23 Apr  1 11:35 HEAD
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 hooks/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 info/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 objects/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 refs/

Lo mismo con git --bare:

me@pc MINGW64 /c/Test
$ ls -al
total 16
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:36 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../

me@pc MINGW64 /c/Test
$ git init --bare
Initialized empty Git repository in C:/Test/

me@pc MINGW64 /c/Test (BARE:master)
$ ls -al
total 23
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 ./
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:11 ../
-rw-r--r-- 1 myid 1049089 104 Apr  1 11:36 config
-rw-r--r-- 1 myid 1049089  73 Apr  1 11:36 description
-rw-r--r-- 1 myid 1049089  23 Apr  1 11:36 HEAD
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 hooks/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 info/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 objects/
Christoph
fuente
2

$ git help repository-layout

Un repositorio de Git viene en dos sabores diferentes:

  • un directorio .git en la raíz del árbol de trabajo;
  • un directorio .git que es un desnudo repositorio (es decir, sin su propio árbol de trabajo), que se utiliza normalmente para intercambiar historias con los demás empujando en él y ir a buscar de ella.
MichK
fuente