Qual è la differenza tra git clone --mirror e git clone --bare


486

La pagina di aiuto del clone git ha questo da dire su --mirror:

Configurare un mirror del repository remoto. Questo implica --bare.

Ma non entra nei dettagli su come il --mirrorclone è diverso da un --bareclone.


3
utile, ma se vuoi anche spingere questo mirror su un repository remoto come github, ho trovato utile questo link .
Mangia da Joes il

Risposte:


569

La differenza è che quando si utilizza --mirror, tutti i riferimenti vengono copiati così come sono . Ciò significa tutto: rami di tracciamento remoto, note, riferimenti / originali / * (backup da filtro-ramo). Il repository clonato ha tutto. È inoltre impostato in modo tale che un aggiornamento remoto recuperi tutto dall'origine (sovrascrivendo i riferimenti copiati). L'idea è davvero quella di eseguire il mirroring del repository, di avere una copia totale, in modo da poter ad esempio ospitare il repository centrale in più posizioni o eseguirne il backup. Pensa di copiare semplicemente il repository, tranne in un modo git molto più elegante.

La nuova documentazione praticamente dice tutto questo:

--mirror

Imposta un mirror del repository di origine. Questo implica --bare. Rispetto a --bare, --mirrornon solo mappa i rami locali della sorgente sui rami locali della destinazione, ma mappa tutti i ref (inclusi rami remoti, note ecc.) E imposta una configurazione refspec in modo tale che tutti questi ref siano sovrascritti da un git remote updaterepository nel target .

La mia risposta originale ha anche notato le differenze tra un clone nudo e un clone normale (non nudo): il clone non nudo imposta rami di tracciamento remoti, creando solo un ramo locale per HEAD, mentre il clone nudo copia direttamente i rami.

Origine Supponiamo che ha un paio di rami ( master (HEAD), next, pue maint), alcuni tag ( v1, v2, v3), alcune filiali remote ( devA/master, devB/master), e di alcuni altri arbitri ( refs/foo/bar, refs/foo/baz, che potrebbe essere note, stashes, i namespace altri sviluppatori, chi lo sa).

  • git clone origin-url(non nudo): Otterrete tutti i tag copiati, una filiale locale master (HEAD)di monitoraggio una filiale remota origin/master, e filiali remote origin/next, origin/pue origin/maint. I rami di tracciamento sono impostati in modo tale che se fai qualcosa del genere git fetch origin, verranno recuperati come previsto. Qualsiasi ramo remoto (nel telecomando clonato) e altri riferimenti vengono completamente ignorati.

  • git clone --bare origin-url: Otterrete tutti i tag copiati, sedi locali master (HEAD), next, pu, e maintmonitoraggio, senza telecomando rami. Cioè, tutti i rami vengono copiati così come sono, ed è impostato completamente indipendente, senza alcuna aspettativa di recupero. Qualsiasi ramo remoto (nel telecomando clonato) e altri riferimenti vengono completamente ignorati.

  • git clone --mirror origin-url: Ogni ultimo di questi riferimenti verrà copiato così com'è. Otterrete tutti i tag, le sezioni locali master (HEAD), next, pu, e maint, filiali remote devA/mastere devB/master, altri arbitri refs/foo/bare refs/foo/baz. Tutto è esattamente come era nel telecomando clonato. Il tracciamento remoto è impostato in modo tale che se si eseguono git remote updatetutti i riferimenti verranno sovrascritti dall'origine, come se si fosse appena eliminato il mirror e lo si fosse richiuso. Come originariamente dicevano i documenti, è uno specchio. Dovrebbe essere una copia funzionalmente identica, intercambiabile con l'originale.


"Clone normale" si riferisce a un clone senza le bandiere --bare o --mirror?
Sam,

1
Sì, lo fa. Con un clone nudo, come dice nella pagina man, anche i rami vengono copiati direttamente (nessun riferimento / telecomando / origine, nessun tracciamento). A cura di.
Cascabel,

Puoi aggiungere qualche altro esempio di utilizzo sulla differenza, non solo sulle differenze interne a git?
cmcginty,

@Casey è quello che stavi cercando? Non pensavo che quello che avevo scritto inizialmente fosse "interno" - tag e rami sono molto tratti di porcellana.
Cascabel,

"Rami copiati così come sono" significa che i rami vengono copiati nello stesso percorso relativo sul clone? O implica che i rami si trasformano in qualche modo?
Sam,

56
$ git clone --mirror $URL

è una scorciatoia per

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

(Copiato direttamente da qui )

Come la pagina man attuale lo dice:

Rispetto a --bare, --mirrornon solo mappa i rami locali della sorgente sui rami locali della destinazione, ma mappa tutti i ref (inclusi rami remoti, note ecc.) E imposta una configurazione refspec in modo tale che tutti questi ref siano sovrascritti da un git remote updaterepository nel target .


4
Credo che dovresti seguirlo con un git fetchperché sia ​​effettivamente identico. Comunque, questa è una specie di non risposta - il punto della domanda è "in che modo un mirror / clone remoto è diverso da uno normale?"
Cascabel,

6
In realtà mi piace questo modo di dimostrare la differenza. Spero che sia preciso! Spero che hfs aggiunga il comando fetch.
joeytwiddle,

non molto chiaro, ad es. cosa sta traducendo $ (basename $ URL), ecc.
Kzqai,

5
basenameè la normale utility unix che rimuove la parte di directory di un percorso ed $()è semplicemente la sostituzione dei comandi di bash.
Victor Zamanian,

6
Questo ha ancora --mirrordentro. Questa sarebbe una risposta accettabile solo se spiegasse cosa git remote add --mirrorfa.
Zenexer,

24

I miei test con git-2.0.0 indicano che l'opzione --mirror non copia gli hook, il file di configurazione, il file di descrizione, il file info / exclude e almeno nel mio caso di test alcuni ref (che non capisco.) Non lo definirei una "copia funzionalmente identica, intercambiabile con l'originale".

-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

14

Una spiegazione sfumata dalla documentazione di GitHub sulla duplicazione di un repository :

Come con un clone nudo, un clone con mirroring include tutti i rami e i tag remoti, ma tutti i riferimenti locali verranno sovrascritti ogni volta che si recupera, quindi sarà sempre lo stesso del repository originale.


1
Grazie; questo mi ha chiarito che i tag locali verranno sovrascritti così come i rami usando un clone con mirroring. Molto utile.
Wildcard il

2
Potresti anche voler usare --prunequando esegui git fetch per rimuovere riferimenti locali che non sono più sul telecomando.
nishanths

13

Un clone copia i riferimenti dal telecomando e li inserisce in una sottodirectory denominata "questi sono i riferimenti che il telecomando ha".

Un mirror copia i riferimenti dal telecomando e li mette al proprio livello superiore - sostituisce i propri riferimenti con quelli del telecomando.

Ciò significa che quando qualcuno si allontana dal tuo mirror e inserisce i riferimenti del mirror nella loro sottodirectory, otterranno gli stessi ref presenti sull'originale. Il risultato del recupero da un mirror aggiornato è lo stesso del recupero direttamente dal repository iniziale.


12

Aggiungo un'immagine, mostro la configdifferenza tra specchio e nudo. inserisci qui la descrizione dell'immagine La sinistra è nuda, la destra è specchio. Puoi essere chiaro, il file di configurazione di mirror ha la fetchchiave, il che significa che puoi aggiornarlo, con git remote updateogit fetch --all


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

Questo comando renderà il nuovo stesso $ GIT_DIR. Anche le teste di diramazione sul telecomando vengono copiate direttamente nelle corrispondenti diramazioni locali, senza mappatura. Quando viene utilizzata questa opzione, non vengono creati né rami di tracciamento remoto né le relative variabili di configurazione.

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

Come con un clone nudo, un clone con mirroring include tutti i rami e i tag remoti, ma tutti i riferimenti locali (inclusi rami di tracciamento remoto, note ecc.) Verranno sovrascritti ogni volta che si recupera, quindi sarà sempre lo stesso del repository originale .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.