Quelle est la différence entre git clone --mirror et git clone --bare

486

La page d'aide de git clone a ceci à dire sur --mirror:

Configurez un miroir du référentiel distant. Cela implique --bare.

Mais n'entre pas dans les détails sur la façon dont le --mirrorclone est différent d'un --bareclone.

Sam
la source
3
utile, mais si vous voulez également pousser ce miroir vers un dépôt distant comme github, j'ai trouvé ce lien pratique.
Mangez chez Joes

Réponses:

569

La différence est que lors de l'utilisation --mirror, toutes les références sont copiées telles quelles . Cela signifie tout: branches de suivi à distance, notes, références / originaux / * (sauvegardes à partir d'une branche de filtre). Le dépôt cloné a tout pour plaire. Il est également configuré pour qu'une mise à jour à distance récupère tout depuis l'origine (écrasant les références copiées). L'idée est vraiment de mettre en miroir le référentiel, d'avoir une copie totale, afin que vous puissiez par exemple héberger votre référentiel central à plusieurs endroits, ou le sauvegarder. Pensez à copier simplement le dépôt, sauf d'une manière beaucoup plus élégante.

La nouvelle documentation dit à peu près tout cela:

--mirror

Configurez un miroir du référentiel source. Cela implique --bare. Comparé à --bare, --mirrornon seulement mappe les branches locales de la source aux branches locales de la cible, il mappe toutes les références (y compris les branches distantes, les notes, etc.) et définit une configuration refspec de sorte que toutes ces références soient écrasées par un git remote updatedans le référentiel cible .

Ma réponse originale a également noté les différences entre un clone nu et un clone normal (non nu) - le clone non nu configure des branches de suivi à distance, créant uniquement une branche locale pour HEAD, tandis que le clone nu copie les branches directement.

Origine On suppose a quelques branches ( master (HEAD), next, puet maint), des balises ( v1, v2, v3), des branches éloignées ( devA/master, devB/master), et quelques autres refs ( refs/foo/bar, refs/foo/baz, ce qui pourrait être des notes, stashes, d' autres espaces de noms de devs, qui sait).

  • git clone origin-url(non-nu): Vous obtiendrez toutes les balises copiés, une branche locale de master (HEAD)suivi d' une branche à distance origin/master, et les branches à distance origin/next, origin/puet origin/maint. Les branches de suivi sont configurées de sorte que si vous faites quelque chose comme ça git fetch origin, elles seront récupérées comme vous vous y attendez. Toutes les branches distantes (dans la télécommande clonée) et autres références sont complètement ignorées.

  • git clone --bare origin-url: Vous obtiendrez toutes les balises copiés, branches locales master (HEAD), next, puet maint, pas de branches de suivi à distance. Autrement dit, toutes les branches sont copiées telles quelles et elles sont configurées de manière totalement indépendante, sans aucune attente de récupération. Toutes les branches distantes (dans la télécommande clonée) et autres références sont complètement ignorées.

  • git clone --mirror origin-url: Chaque dernière de ces références sera copiée telle quelle. Vous aurez toutes les balises, les branches locales master (HEAD), next, puet maint, branches à distance devA/masteret devB/master, d' autres refs refs/foo/baret refs/foo/baz. Tout est exactement comme dans la télécommande clonée. Le suivi à distance est configuré de sorte que si vous exécutez git remote updatetoutes les références seront écrasées depuis l'origine, comme si vous veniez de supprimer le miroir et de le recloner. Comme les docs l'ont dit à l'origine, c'est un miroir. Il est censé être une copie fonctionnellement identique, interchangeable avec l'original.

Cascabel
la source
Le "clone normal" fait-il référence à un clone sans les indicateurs --bare ou --mirror?
Sam
1
Oui cela le fait. Avec un clone nu, comme il est dit sur la page de manuel, les branches sont également copiées directement (pas de références / télécommandes / origine, pas de suivi). Modifié en.
Cascabel
Pouvez-vous ajouter un exemple d'utilisation supplémentaire sur la différence, pas seulement les différences internes à git?
cmcginty
@Casey, c'est ce que vous cherchiez? Je ne pensais pas du tout que ce que j'avais écrit à l'origine était "interne" - les étiquettes et les branches sont beaucoup des éléments en porcelaine.
Cascabel
Est-ce que "branches copiées telles quelles" signifie que les branches sont copiées sur le même chemin relatif sur le clone? Ou cela implique-t-il que les branches sont transformées d'une manière ou d'une autre?
Sam
56
$ git clone --mirror $URL

est un raccourci pour

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

(Copié directement à partir d' ici )

Comment la page de manuel actuelle l'exprime:

Comparé à --bare, --mirrornon seulement mappe les branches locales de la source aux branches locales de la cible, il mappe toutes les références (y compris les branches distantes, les notes, etc.) et définit une configuration refspec de sorte que toutes ces références soient écrasées par un git remote updatedans le référentiel cible .

hfs
la source
4
Je pense qu'il faudrait suivre cela avec un git fetchpour qu'il soit réellement identique. Quoi qu'il en soit, c'est une sorte de non-réponse - le point de la question est "en quoi un miroir / clone distant est-il différent d'un miroir normal?"
Cascabel
6
J'aime vraiment cette façon de montrer la différence. J'espère que c'est exact! J'espère que hfs ajoute la commande fetch.
joeytwiddle
pas vraiment clair, par exemple ce que $ (basename $ URL) traduit, etc.
Kzqai
5
basenameest l'utilitaire Unix normal qui supprime la partie répertoire d'un chemin, et $()est simplement la substitution de commandes de bash.
Victor Zamanian
6
Cela a encore --mirroren elle. Ce ne serait une réponse acceptable que si elle expliquait ce qui se git remote add --mirrorpassait.
Zenexer
24

Mes tests avec git-2.0.0 aujourd'hui indiquent que l'option --mirror ne copie pas les hooks, le fichier de configuration, le fichier de description, le fichier info / exclude, et au moins dans mon cas de test quelques références (dont je ne fais pas '' t comprendre.) Je ne l'appellerais pas une "copie fonctionnellement identique, interchangeable avec l'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
la source
14

Une explication nuancée de la documentation GitHub sur la duplication d'un référentiel :

Comme avec un clone nu, un clone en miroir inclut toutes les branches et balises distantes, mais toutes les références locales seront écrasées à chaque fois que vous les récupérez, ce sera donc toujours la même que le référentiel d'origine.

Feckmore
la source
1
Je vous remercie; cela a précisé pour moi que les balises locales seront écrasées ainsi que les branches en utilisant un clone en miroir. Très utile.
Wildcard du
2
Vous pouvez également utiliser --prunelors de l'exécution de git fetch pour supprimer les références locales qui ne se trouvent plus sur la télécommande.
nishanths
13

Un clone copie les références de la télécommande et les place dans un sous-répertoire nommé «ce sont les références de la télécommande».

Un miroir copie les références de la télécommande et les place dans son propre niveau supérieur - il remplace ses propres références par celles de la télécommande.

Cela signifie que lorsque quelqu'un sort de votre miroir et place les références du miroir dans son sous-répertoire, il obtient les mêmes références que celles de l'original. Le résultat de la récupération à partir d'un miroir à jour est le même que la récupération directe à partir du référentiel initial.

PaulMurrayCbr
la source
12

J'ajoute une image, montre la configdifférence entre le miroir et le nu. entrez la description de l'image ici La gauche est nue, la droite est miroir. Vous pouvez être clair, le fichier de configuration du miroir a une fetchclé, ce qui signifie que vous pouvez le mettre à jour, par git remote updateougit fetch --all

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

Cette commande fera du nouveau lui-même $ GIT_DIR. De plus, les têtes de branche à distance sont copiées directement dans les têtes de branche locales correspondantes, sans mappage. Lorsque cette option est utilisée, ni les branches de suivi à distance ni les variables de configuration associées ne sont créées.

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

Comme avec un clone nu, un clone en miroir inclut toutes les branches et balises distantes, mais toutes les références locales (y compris les branches de suivi à distance, les notes, etc.) seront écrasées à chaque fois que vous récupérez, donc ce sera toujours le même que le référentiel d'origine .

Shantanu Singh
la source