Was ist der Unterschied zwischen git clone --mirror und git clone --bare?

486

Die Hilfeseite für Git-Klone enthält Folgendes --mirror:

Richten Sie einen Spiegel des Remote-Repositorys ein. Dies impliziert --bare.

Geht aber nicht ins Detail, wie sich der --mirrorKlon von einem --bareKlon unterscheidet.

Sam
quelle
3
hilfreich, aber wenn Sie diesen Spiegel auch auf ein Remote-Repo wie Github schieben möchten, fand ich diesen Link praktisch.
Essen Sie bei Joes

Antworten:

569

Der Unterschied ist , dass bei der Verwendung --mirror, alle sind Refs kopiert , wie sie ist . Dies bedeutet alles: Remote-Tracking-Zweige, Notizen, Refs / Originale / * (Backups von Filter-Branch). Das geklonte Repo hat alles. Es ist auch so eingerichtet, dass ein Remote-Update alles vom Ursprung erneut abruft (Überschreiben der kopierten Refs). Die Idee ist wirklich, das Repository zu spiegeln, um eine Gesamtkopie zu erhalten, so dass Sie beispielsweise Ihr zentrales Repo an mehreren Stellen hosten oder sichern können. Denken Sie nur daran, das Repo direkt zu kopieren, außer auf eine viel elegantere Art und Weise.

Die neue Dokumentation sagt so ziemlich alles:

--mirror

Richten Sie einen Spiegel des Quell-Repositorys ein. Dies impliziert --bare. Im Vergleich dazu --barewerden --mirrornicht nur lokale Zweige der Quelle lokalen Zweigen des Ziels zugeordnet, sondern alle Refs (einschließlich entfernter Zweige, Notizen usw.) zugeordnet und eine Refspec-Konfiguration eingerichtet, sodass alle diese Refs von a git remote updateim Ziel-Repository überschrieben werden .

In meiner ursprünglichen Antwort wurden auch die Unterschiede zwischen einem nackten Klon und einem normalen (nicht nackten) Klon festgestellt. Der nicht nackte Klon richtet Remote-Tracking-Zweige ein und erstellt nur einen lokalen Zweig für HEAD , während der nackte Klon die Zweige direkt kopiert.

Angenommen Ursprung hat ein paar Zweige ( master (HEAD), next, puund maint), einige Tags ( v1, v2, v3), einige entfernte Zweige ( devA/master, devB/master) und einige andere Refs ( refs/foo/bar, refs/foo/baz, welche Noten sein könnte, stashes, andere Devs' Namespaces, wer weiß).

  • git clone origin-url(non-blank): Sie werden alle Tags erhalten kopiert, eine lokale Niederlassung master (HEAD)eines Remote - Zweig - Tracking origin/masterund Remote - Niederlassungen origin/next, origin/puund origin/maint. Die Tracking-Zweige sind so eingerichtet, dass git fetch originsie wie erwartet abgerufen werden , wenn Sie so etwas tun . Alle Remote-Zweige (in der geklonten Remote) und andere Refs werden vollständig ignoriert.

  • git clone --bare origin-url: Sie werden alle Tags kopiert, lokale Niederlassungen erhalten master (HEAD), next, pu, und maint, keine Fern Tracking Filialen. Das heißt, alle Zweige werden unverändert kopiert und sind völlig unabhängig eingerichtet, ohne dass ein erneutes Abrufen zu erwarten ist. Alle Remote-Zweige (in der geklonten Remote) und andere Refs werden vollständig ignoriert.

  • git clone --mirror origin-url: Jeder letzte dieser Refs wird unverändert kopiert. Sie werden alle Tags, lokale Niederlassungen erhalten master (HEAD), next, pu, und maint, Fern Zweige devA/masterund devB/masterandere Refs refs/foo/barund refs/foo/baz. Alles ist genau so wie es in der geklonten Fernbedienung war. Die Fernverfolgung ist so eingerichtet, dass beim Ausführen git remote updatealle Refs vom Ursprung überschrieben werden, als hätten Sie den Spiegel gerade gelöscht und neu geklont. Wie die Dokumente ursprünglich sagten, ist es ein Spiegel. Es soll eine funktional identische Kopie sein, die mit dem Original austauschbar ist.

Cascabel
quelle
Bezieht sich "normaler Klon" auf einen Klon ohne die Flags --bare oder --mirror?
Sam
1
Ja das tut es. Mit einem nackten Klon, wie es auf der Manpage steht, werden Zweige auch direkt kopiert (keine Refs / Fernbedienungen / Herkunft, keine Verfolgung). Bearbeitet in.
Cascabel
Können Sie ein weiteres Anwendungsbeispiel für den Unterschied hinzufügen, nicht nur für die git-internen Unterschiede?
cmcginty
@Casey ist das was du gesucht hast? Ich dachte nicht, dass das, was ich ursprünglich schrieb, überhaupt "intern" war - Tags und Zweige sind sehr viel Porzellan.
Cascabel
Bedeutet "Zweige wie sie sind kopiert", dass Zweige auf denselben relativen Pfad im Klon kopiert werden? Oder bedeutet es, dass Zweige auf irgendeine Weise transformiert werden?
Sam
56
$ git clone --mirror $URL

ist eine Abkürzung für

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

(Direkt von hier kopiert )

Wie die aktuelle Manpage es ausdrückt:

Im Vergleich dazu --barewerden --mirrornicht nur lokale Zweige der Quelle lokalen Zweigen des Ziels zugeordnet, sondern alle Refs (einschließlich entfernter Zweige, Notizen usw.) zugeordnet und eine Refspec-Konfiguration eingerichtet, sodass alle diese Refs von a git remote updateim Ziel-Repository überschrieben werden .

hfs
quelle
4
Ich glaube, Sie git fetchmüssten dem mit einem folgen, damit es tatsächlich identisch ist. Wie auch immer, dies ist eine Art Nichtantwort - der Punkt der Frage ist "Wie unterscheidet sich eine Spiegelfernbedienung / ein Spiegelklon von einer normalen?"
Cascabel
6
Ich mag diese Art, den Unterschied zu demonstrieren. Hoffentlich ist es richtig! Ich hoffe, hfs fügt den Befehl fetch hinzu.
Joeytwiddle
nicht wirklich klar, zB was bedeutet $ (Basisname $ URL) usw.
Kzqai
5
basenameist das normale Unix-Dienstprogramm, das den Verzeichnisteil eines Pfads entfernt und $()einfach die Befehlsersetzung von bash ist.
Victor Zamanian
6
Das hat noch --mirrordrin. Dies wäre nur dann eine akzeptable Antwort, wenn erklärt würde, was git remote add --mirrorfunktioniert.
Zenexer
24

Meine heutigen Tests mit git-2.0.0 zeigen, dass die Option --mirror keine Hooks, die Konfigurationsdatei, die Beschreibungsdatei, die Info- / Ausschlussdatei und zumindest in meinem Testfall einige Refs (die ich nicht benutze) kopiert. Ich verstehe es nicht als "funktional identische Kopie, austauschbar mit dem 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
quelle
14

Eine differenzierte Erklärung aus der GitHub-Dokumentation zum Duplizieren eines Repositorys :

Wie bei einem nackten Klon enthält ein gespiegelter Klon alle Remote-Zweige und -Tags, aber alle lokalen Referenzen werden bei jedem Abruf überschrieben, sodass er immer mit dem ursprünglichen Repository identisch ist.

Feckmore
quelle
1
Vielen Dank; Dadurch wurde für mich klargestellt, dass lokale Tags sowie Verzweigungen mithilfe eines gespiegelten Klons überschrieben werden. Sehr hilfreich.
Wildcard
2
Möglicherweise möchten Sie --prunebeim Ausführen von git fetch auch lokale Verweise entfernen, die sich nicht mehr auf der Remote befinden.
Nishanths
13

Ein Klon kopiert die Refs von der Fernbedienung und stopft sie in ein Unterverzeichnis mit dem Namen "Dies sind die Refs, über die die Fernbedienung verfügt".

Ein Spiegel kopiert die Refs von der Fernbedienung und versetzt sie in eine eigene oberste Ebene. Er ersetzt seine eigenen Refs durch die der Fernbedienung.

Dies bedeutet, dass jemand, der aus Ihrem Spiegel zieht und die Refs des Spiegels in sein Unterverzeichnis stopft, die gleichen Refs erhält wie auf dem Original. Das Ergebnis des Abrufs von einem aktuellen Spiegel ist das gleiche wie das Abrufen direkt vom ursprünglichen Repo.

PaulMurrayCbr
quelle
12

Ich füge ein Bild hinzu, zeige den configUnterschied zwischen Spiegel und nackt. Geben Sie hier die Bildbeschreibung ein Die linke ist kahl, die rechte ist der Spiegel. Sie können klar sein, dass die Konfigurationsdatei des Spiegels einen fetchSchlüssel hat, was bedeutet, dass Sie ihn durch git remote updateoder aktualisieren könnengit fetch --all

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

Dieser Befehl macht das Neue selbst zum $ GIT_DIR. Auch die Verzweigungsköpfe auf der Fernbedienung werden ohne Zuordnung direkt in die entsprechenden lokalen Verzweigungsköpfe kopiert. Wenn diese Option verwendet wird, werden weder Remote-Tracking-Zweige noch die zugehörigen Konfigurationsvariablen erstellt.

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

Wie bei einem nackten Klon enthält ein gespiegelter Klon alle Remote-Zweige und -Tags, aber alle lokalen Verweise (einschließlich Remote-Tracking-Zweige, Notizen usw.) werden bei jedem Abruf überschrieben, sodass sie immer mit dem ursprünglichen Repository identisch sind .

Shantanu Singh
quelle