¿Cuál es la diferencia entre git clone --mirror y git clone --bare

486

La página de ayuda de git clone tiene esto que decir sobre --mirror:

Configure un espejo del repositorio remoto. Esto implica --bare.

Pero no entra en detalles sobre cómo el --mirrorclon es diferente de un --bareclon.

Sam
fuente
3
útil, pero si también desea llevar este espejo a un repositorio remoto como github, este enlace me parece útil.
Comer en Joes

Respuestas:

569

La diferencia es que cuando se usa --mirror, todas las referencias se copian tal como están . Esto significa todo: ramas de seguimiento remoto, notas, referencias / originales / * (copias de seguridad de rama de filtro). El repositorio clonado lo tiene todo. También está configurado para que una actualización remota vuelva a buscar todo desde el origen (sobrescribiendo las referencias copiadas). La idea es realmente reflejar el repositorio, tener una copia total, de modo que pueda, por ejemplo, alojar su repositorio central en varios lugares o hacer una copia de seguridad. Piense en copiar directamente el repositorio, excepto de una manera mucho más elegante.

La nueva documentación dice más o menos todo esto:

--mirror

Configure un espejo del repositorio de origen. Esto implica --bare. En comparación con --bare, --mirrorno solo asigna las ramas locales de la fuente a las ramas locales del objetivo, sino que asigna todas las referencias (incluidas las ramas remotas, notas, etc.) y establece una configuración de referencia de modo que todas estas referencias sean sobrescritas por un git remote updateen el repositorio de destino .

Mi respuesta original también señaló las diferencias entre un clon desnudo y un clon normal (no desnudo): el clon no desnudo configura ramas de seguimiento remoto, solo crea una rama local para HEAD, mientras que el clon desnudo copia las ramas directamente.

Origen Supongamos que tiene un par de ramas ( master (HEAD), next, pu, y maint), algunas etiquetas ( v1, v2, v3), algunas ramas remotas ( devA/master, devB/master), y algunas otras referencias ( refs/foo/bar, refs/foo/baz, que podría ser notas, alijos, espacios de nombres otros devs', quien sabe).

  • git clone origin-url(no desnudo): Usted recibirá todas las etiquetas copiadas, una rama local de master (HEAD)seguimiento de una rama remota origin/master, y sucursales remotas origin/next, origin/puy origin/maint. Las ramas de seguimiento están configuradas de modo que si hace algo así git fetch origin, se buscarán como espera. Cualquier rama remota (en el control remoto clonado) y otras referencias se ignoran por completo.

  • git clone --bare origin-url: Usted recibirá todas las etiquetas copiadas, ramas locales master (HEAD), next, pu, y maintramas de seguimiento, sin control remoto. Es decir, todas las ramas se copian tal cual, y se configura de manera completamente independiente, sin expectativas de volver a buscar. Cualquier rama remota (en el control remoto clonado) y otras referencias se ignoran por completo.

  • git clone --mirror origin-url: Cada uno de esos referentes se copiará tal cual. Usted obtendrá todas las etiquetas, las ramas locales master (HEAD), next, pu, y maint, ramas remotas devA/mastery devB/master, otros árbitros refs/foo/bary refs/foo/baz. Todo está exactamente como estaba en el control remoto clonado. El seguimiento remoto se configura de modo que si ejecuta git remote updatetodas las referencias se sobrescribirán desde el origen, como si acabara de eliminar el espejo y volverlo a colocar. Como los documentos originalmente decían, es un espejo. Se supone que es una copia funcionalmente idéntica, intercambiable con el original.

Cascabel
fuente
¿"Clon normal" se refiere a un clon sin las banderas --bare o --mirror?
Sam
1
Sí lo hace. Con un clon desnudo, como dice en la página del manual, las ramas también se copian directamente (sin referencias / controles remotos / origen, sin seguimiento). Editado en.
Cascabel
¿Puedes agregar más ejemplos de uso sobre la diferencia, no solo sobre las diferencias internas de git?
cmcginty
@Casey, ¿es eso lo que estabas buscando? No pensé que lo que escribí originalmente fuera "interno" en absoluto: las etiquetas y las ramas son características de porcelana.
Cascabel
¿"Ramas copiadas como están" significa que las ramas se copian en la misma ruta relativa en el clon? ¿O implica que las ramas se transforman de alguna manera?
Sam
56
$ git clone --mirror $URL

es una abreviatura para

$ git clone --bare $URL
$ (cd $(basename $URL) && git remote add --mirror=fetch origin $URL)

(Copiado directamente de aquí )

Cómo lo expresa la página de manual actual:

En comparación con --bare, --mirrorno solo asigna las ramas locales de la fuente a las ramas locales del objetivo, sino que asigna todas las referencias (incluidas las ramas remotas, notas, etc.) y establece una configuración de referencia de modo que todas estas referencias sean sobrescritas por un git remote updateen el repositorio de destino .

hfs
fuente
44
Creo que tendrías que seguir eso con un git fetchpara que sea realmente idéntico. De todos modos, esto es una especie de no respuesta: el punto de la pregunta es "¿en qué se diferencia un espejo remoto / clon de uno normal?"
Cascabel
66
De hecho, me gusta esta forma de demostrar la diferencia. ¡Ojalá sea exacto! Espero que hfs agregue el comando fetch.
joeytwiddle
no está realmente claro, por ejemplo, qué se traduce en $ (basename $ URL), etc.
Kzqai
55
basenamees la utilidad normal de Unix que elimina la parte del directorio de una ruta, y $()es simplemente la sustitución de comandos de bash.
Victor Zamanian
66
Esto todavía tiene --mirroren él. Esto solo sería una respuesta aceptable si explicara lo que git remote add --mirrorhace.
Zenexer
24

Mis pruebas con git-2.0.0 hoy indican que la opción --mirror no copia los ganchos, el archivo de configuración, el archivo de descripción, el archivo de información / exclusión y, al menos en mi caso de prueba, algunas referencias (lo cual no hago ' no entiendo.) No lo llamaría una "copia funcionalmente idéntica, intercambiable con el original".

-bash-3.2$ git --version
git version 2.0.0
-bash-3.2$ git clone --mirror /git/hooks
Cloning into bare repository 'hooks.git'...
done.

-bash-3.2$ diff --brief -r /git/hooks.git hooks.git
Files /git/hooks.git/config and hooks.git/config differ
Files /git/hooks.git/description and hooks.git/description differ
...
Only in hooks.git/hooks: applypatch-msg.sample
...
Only in /git/hooks.git/hooks: post-receive
...
Files /git/hooks.git/info/exclude and hooks.git/info/exclude differ
...
Files /git/hooks.git/packed-refs and hooks.git/packed-refs differ
Only in /git/hooks.git/refs/heads: fake_branch
Only in /git/hooks.git/refs/heads: master
Only in /git/hooks.git/refs: meta
Mark E. Hamilton
fuente
14

Una explicación matizada de la documentación de GitHub sobre Duplicar un repositorio :

Al igual que con un clon desnudo, un clon reflejado incluye todas las ramas y etiquetas remotas, pero todas las referencias locales se sobrescribirán cada vez que obtenga, por lo que siempre será el mismo que el repositorio original.

Feckmore
fuente
1
Gracias; Esto me aclaró que las etiquetas locales se sobrescribirán, así como las ramas, mediante el uso de un clon reflejado. Muy útil.
Comodín el
2
Es posible que también desee usar --pruneal ejecutar git fetch para eliminar referencias locales que ya no están en el control remoto.
nishanths
13

Un clon copia las referencias del control remoto y las guarda en un subdirectorio llamado 'estas son las referencias que tiene el control remoto'.

Un espejo copia las referencias del control remoto y las coloca en su propio nivel superior: reemplaza sus propias referencias con las del control remoto.

Esto significa que cuando alguien tira de su espejo y mete las referencias del espejo en su subdirectorio, obtendrá las mismas referencias que en el original. El resultado de buscar desde un espejo actualizado es lo mismo que buscar directamente desde el repositorio inicial.

PaulMurrayCbr
fuente
12

Agrego una imagen, muestro la configdiferencia entre espejo y desnudo. ingrese la descripción de la imagen aquí La izquierda está desnuda, la derecha es espejo. Puede ser claro, el archivo de configuración del espejo tiene fetchclave, lo que significa que puede actualizarlo, por git remote updateogit fetch --all

yanzi1225627
fuente
3
$ git clone --bare https://github.com/example

Este comando hará que el nuevo sea el $ GIT_DIR. Además, las cabeceras de sucursal en el control remoto se copian directamente a las correspondientes sucursales locales, sin mapeo. Cuando se utiliza esta opción, no se crean ramas de seguimiento remoto ni las variables de configuración relacionadas.

$ git clone --mirror https://github.com/example

Al igual que con un clon desnudo, un clon duplicado incluye todas las ramas y etiquetas remotas, pero todas las referencias locales (incluidas las ramas de seguimiento remoto, notas, etc.) se sobrescribirán cada vez que vaya a buscar, por lo que siempre será el mismo que el repositorio original .

Shantanu Singh
fuente