Was ist der praktische Unterschied zwischen einem Bare- und einem Nicht-Bare-Repository?

213

Ich habe über die nackten und nicht nackten / Standard-Repositores in Git gelesen. Ich war nicht in der Lage, (theoretisch) die Unterschiede zwischen ihnen zu verstehen und warum ich in ein nacktes Repository "pushen" sollte. Das ist der Deal:

Derzeit bin ich der einzige, der an einem Projekt auf 3 verschiedenen Computern arbeitet, aber später werden mehr Leute daran beteiligt sein, daher verwende ich Git für die Versionskontrolle. Ich klone das Bare-Repo auf allen Computern, und wenn ich meine Änderungen an einem von ihnen abgeschlossen habe, übertrage ich die Änderungen und übertrage sie auf das Bare-Repo. Nach dem, was ich gelesen habe, hat das Bare-Repository KEINEN "Arbeitsbaum". Wenn ich also das Bare-Repo klone, habe ich keinen "Arbeitsbaum".

Ich vermute, dass der Arbeitsbaum die Festschreibungsinformationen, Zweige usw. aus dem Projekt speichert. Das würde nicht im nackten Repo erscheinen. Daher scheint es für mich besser zu sein, die Commits mit dem Arbeitsbaum zum Repo zu "pushen".

Dann warum soll ich das blanke Repository verwenden und warum nicht? Was ist der praktische Unterschied? Das wäre wohl nicht vorteilhaft für mehr Leute, die an einem Projekt arbeiten.

Was sind Ihre Methoden für diese Art von Arbeit? Vorschläge?

AeroCross
quelle
4
AeroCross, Sie können mit einem nackten Repository klonen ein nicht-bare Repository zu erstellen (das heißt, eine , die einen Arbeitsbereich hat). Mit können git cloneSie also frei zwischen nackten und nicht nackten Repositorys konvertieren.
Derek Mahar
13
@AeroCross: Es geht nicht um Konvertierung; Es ist egal, was am anderen Ende ist. Wenn du git clone --barerennst, bekommst du ein nacktes Repo, und wenn du rennst git clone, bekommst du ein nicht nacktes. Jedes öffentliche Projekt, das Sie jemals geklont haben (z. B. auf Github gehostet), ist am anderen Ende ein nacktes Repository.
Cascabel
1
Jefromi, ich habe den Punkt von AeroCross korrigiert. "Wenn ich also das nackte Repo klone, habe ich keinen" funktionierenden Baum ". Es handelt sich also um eine Art Konvertierung. Und nicht jedes öffentliche Projekt muss ein reines Repository sein. Dies ist nur die typische Wahl, da ein nacktes Repository platzsparender ist, da es keinen Arbeitsbaum hat (es ist jedoch genauso platzsparend wie jedes Repository, das keinen Arbeitsbaum hat).
Derek Mahar
2
@Derek: Aber der Punkt ist, dass das Abrufen, sobald es das .git-Verzeichnis findet, überhaupt nicht weiß, ob die Fernbedienung leer ist oder nicht. Es konvertiert nicht. Es ruft nur das ab, was es von der Fernbedienung benötigt, und legt es dort ab, wo es hingehört. Es gibt nichts zu konvertieren. Das wollte ich dem OP gegenüber betonen. Und mir ist klar, dass öffentliche Projekte nicht bloß sein müssen, aber weil die Leute nicht dumm sind, sind sie es im Wesentlichen alle. Ich denke, ich habe eine akzeptable Verallgemeinerung gemacht.
Cascabel
2
Siehe Push to Non-Bare-Repository, das eine weitere hervorragende Erklärung für die Verwendung von Bare-Repository enthält.
Craig McQueen

Antworten:

95

Ein weiterer Unterschied zwischen einem nackten und einem nicht nackten Repository besteht darin, dass ein nacktes Repository kein Standard-Remote- Ursprungs- Repository hat:

~/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

Aus der Handbuchseite für git clone --bare:

Außerdem werden die Verzweigungsköpfe auf der Fernbedienung direkt in die entsprechenden lokalen Verzweigungsköpfe kopiert, ohne sie auf refs / remotes / origin / abzubilden. Wenn diese Option verwendet wird, werden weder Fernverfolgungszweige noch die zugehörigen Konfigurationsvariablen erstellt.

Vermutlich geht Git beim Erstellen eines Bare-Repositorys davon aus, dass das Bare-Repository als Ursprungs-Repository für mehrere Remote-Benutzer dient, sodass nicht der Standard-Remote-Ursprung erstellt wird. Dies bedeutet, dass Basic git pullund git pushOperationen nicht funktionieren, da Git davon ausgeht, dass Sie ohne Arbeitsbereich keine Änderungen am nackten Repository vornehmen möchten:

~/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
quelle
1
Ja, ich stimme zu, dass dies wohl der bedeutendste Unterschied zwischen nackten und nicht nackten Git-Repositories ist. Die Tatsache, dass ein nicht nacktes Repository einen Arbeitsbereich hat, ein nacktes Repository jedoch keinen wichtigen Unterschied, git clone --no-checkoutkann jedoch auch ein nicht nacktes Repository ohne Arbeitsbereichsdateien erstellen.
Derek Mahar
10
Ein nicht nacktes Repository hat auch nicht unbedingt einen Standard-Remote- "Ursprung".
Mipadi
2
Sie können einfach mit ein Git-Repository git initerstellen, das ein nicht nacktes Repo ohne Remote-Angabe erstellt.
Mipadi
1
Mipadi, das ist wahr, aber es ist auch kein Klon.
Derek Mahar
1
Das ist falsch. Ein Repository hat einen Standardursprung, wenn es clonebearbeitet wurde. Wenn es initlokal bearbeitet wurde, hat es keinen solchen Ursprung. Dies hat nichts damit zu tun, ob es kahl ist oder nicht.
Noufal Ibrahim
62

Die Unterscheidung zwischen einem nackten und einem nicht nackten Git-Repository ist künstlich und irreführend, da ein Arbeitsbereich nicht Teil des Repositorys ist und ein Repository keinen Arbeitsbereich benötigt. Genau genommen enthält ein Git-Repository diejenigen Objekte, die den Status des Repositorys beschreiben. Diese Objekte können in einem beliebigen Verzeichnis vorhanden sein, befinden sich jedoch normalerweise im .gitVerzeichnis im obersten Verzeichnis des Arbeitsbereichs. Der Arbeitsbereich ist ein Verzeichnisbaum, der ein bestimmtes Commit im Repository darstellt, aber in jedem Verzeichnis vorhanden sein kann oder überhaupt nicht. Die Umgebungsvariable $GIT_DIRverknüpft einen Arbeitsbereich mit dem Repository, aus dem er stammt.

Git-Befehle git cloneund git initbeide haben Optionen --bare, mit denen Repositorys ohne anfänglichen Arbeitsbereich erstellt werden. Es ist bedauerlich, dass Git die beiden getrennten, aber verwandten Konzepte von Arbeitsbereich und Repository zusammenführt und dann den verwirrenden Begriff bare verwendet , um die beiden Ideen zu trennen.

Derek Mahar
quelle
61

Ein nacktes Repository ist nichts anderes als der .git- Ordner selbst, dh der Inhalt eines nackten Repositorys entspricht dem Inhalt des .git- Ordners in Ihrem lokalen Arbeitsrepository.

  • Verwenden Sie das Bare-Repository auf einem Remote-Server, damit mehrere Mitwirkende ihre Arbeit vorantreiben können.
  • Nicht nackt - Der mit dem Arbeitsbaum ist auf dem lokalen Computer jedes Mitwirkenden Ihres Projekts sinnvoll.
Deepak Sharma
quelle
60

5 Jahre zu spät, ich weiß, aber niemand hat die Frage tatsächlich beantwortet:

Warum sollte ich dann das nackte Repository verwenden und warum nicht? Was ist der praktische Unterschied? Das wäre wohl nicht vorteilhaft für mehr Leute, die an einem Projekt arbeiten.

Was sind Ihre Methoden für diese Art von Arbeit? Vorschläge?

Um direkt aus dem Loeliger / MCullough-Buch (978-1-449-31638-9, S. 196/7) zu zitieren:

Ein nacktes Repository scheint wenig nützlich zu sein, aber seine Rolle ist entscheidend: als maßgeblicher Mittelpunkt für die gemeinsame Entwicklung zu dienen. Andere Entwickler cloneund fetchaus dem Bare-Repository und pushAktualisierungen ... Wenn Sie ein Repository einrichten, in das Entwickler pushwechseln, sollte es Bare sein. Tatsächlich ist dies ein Sonderfall der allgemeineren Best Practice, dass ein veröffentlichtes Repository leer sein sollte.

EML
quelle
19

Ein nicht nacktes Repository verfügt lediglich über einen ausgecheckten Arbeitsbaum. Der Arbeitsbaum speichert keine Informationen über den Status des Repositorys (Zweige, Tags usw.). Vielmehr ist der Arbeitsbaum nur eine Darstellung der tatsächlichen Dateien im Repo, mit denen Sie die Dateien bearbeiten (bearbeiten usw.) können.

Mipadi
quelle
Das bedeutet also, dass ich Zweige, Tags usw. zum nackten Repository hinzufügen und dann vom nackten zum nicht nackten / Produktions-Repository ziehen kann?
AeroCross
2
mipadi, ein nicht nacktes Repository, hat möglicherweise keinen ausgecheckten Baum. Dies ist der Fall, wenn Sie ein nicht nacktes Repository mit erstellen git clone --no-checkout. In diesem Fall hat das nicht nackte Repository einen Speicherort für den Arbeitsbereich, aber Git checkt keine Dateien in diesen Arbeitsbereich aus.
Derek Mahar
17

Ein nacktes Repository hat Vorteile in

  • reduzierte Festplattennutzung
  • weniger Probleme im Zusammenhang mit Remote-Push (da kein funktionierender Baum vorhanden ist, um nicht mehr synchron zu sein oder widersprüchliche Änderungen vorzunehmen)
sehe sehen
quelle
3
Das nackte Repository ist also die beste / empfohlene Methode, um mit mehreren Personen ohne Zugriff auf IHRE Repositorys zu arbeiten? (Ein
bisschen
2
AeroCross, ich würde sagen, ein nacktes Repository ist eine gute Wahl für dieses Szenario.
Derek Mahar
12

Mit dem nicht nackten Repository können Sie (in Ihrem Arbeitsbaum) Änderungen erfassen, indem Sie neue Commits erstellen.

Bloße Repositorys werden nur durch den Transport von Änderungen aus anderen Repositorys geändert.

Nitin
quelle
10

Ich bin sicher kein Git "Experte". Ich habe TortoiseGit für eine Weile verwendet und mich gefragt, worüber es sprach, als ich gefragt wurde, ob ich bei jeder Erstellung ein "nacktes" Repo machen möchte. Ich habe dieses Tutorial gelesen: https://www.atlassian.com/git/tutorials/setting-up-a-repository/git-init und es behebt das Problem, aber ich habe das Konzept immer noch nicht ganz verstanden. Dieser hat sehr geholfen: http://bitflop.com/tutorials/git-bare-vs-non-bare-repositories.html . Jetzt macht auch der erste Sinn!

Diesen Quellen zufolge wird kurz gesagt ein "nacktes" Repo auf einem Server verwendet, auf dem Sie einen Verteilungspunkt einrichten möchten. Es ist nicht für die Verwendung auf Ihrem lokalen Computer vorgesehen. Im Allgemeinen übertragen Sie Commits von Ihrem lokalen Computer auf ein Bare-Repo auf einem Remote-Server, und Sie und / oder andere ziehen von diesem Bare-Repo auf Ihren lokalen Computer. Ihr GitHub-, Assembla- usw. Remote-Speicher- / Distributions-Repo ist also ein Beispiel, in dem ein "nacktes" Repo erstellt wird. Sie würden selbst eines erstellen, wenn Sie Ihr eigenes analoges "Sharing Center" einrichten würden.

BuvinJ
quelle
ooooh jetzt
verstehe
9

Ein Standard- / nicht nacktes Git-Repo enthält zwei Statuselemente:

  1. Ein Schnappschuss aller Dateien im Repository (dies bedeutet "Arbeitsbaum" im Git-Jargon).
  2. Eine Historie aller Änderungen, die an allen Dateien vorgenommen wurden, die jemals im Repository waren (es scheint kein prägnantes Stück Git-Jargon zu geben, das all dies umfasst).

Der Schnappschuss ist das, was Sie wahrscheinlich als Ihr Projekt betrachten: Ihre Codedateien, Build-Dateien, Hilfsskripte und alles andere, was Sie mit Git versionieren.

Der Verlauf ist der Status, mit dem Sie ein anderes Commit auschecken und einen vollständigen Überblick darüber erhalten können, wie die Dateien in Ihrem Repository ausgesehen haben, als dieses Commit hinzugefügt wurde. Es besteht aus einer Reihe von Git-internen Datenstrukturen, mit denen Sie wahrscheinlich noch nie direkt interagiert haben. Wichtig ist, dass im Verlauf nicht nur Metadaten gespeichert werden (z. B. "Benutzer U hat zum Zeitpunkt T im Rahmen von Commit C so viele Zeilen zu Datei F hinzugefügt"), sondern auch Daten (z. B. "Benutzer U hat diese genauen Zeilen zu Datei F hinzugefügt "). ).

Die Schlüsselidee eines nackten Repositorys ist, dass Sie den Snapshot nicht benötigen. Git behält den Snapshot bei, da er für Menschen und andere Nicht-Git-Prozesse geeignet ist, die mit Ihrem Code interagieren möchten. Der Snapshot dupliziert jedoch nur den Status, der bereits in der Historie enthalten ist.

Ein nacktes Repository ist ein Git-Repository ohne Snapshot. Es speichert nur die Geschichte.

Warum willst du das? Wenn Sie nur mit Git mit Ihren Dateien interagieren (dh Ihre Dateien nicht direkt bearbeiten oder zum Erstellen einer ausführbaren Datei verwenden), können Sie Platz sparen, indem Sie den Snapshot nicht beibehalten. Insbesondere wenn Sie eine zentralisierte Version Ihres Repos auf einem Server irgendwo verwalten (dh Sie hosten im Grunde Ihren eigenen GitHub), sollte dieser Server wahrscheinlich ein nacktes Repo haben (Sie würden immer noch ein nicht nacktes Repo auf Ihrem verwenden lokaler Computer, da Sie vermutlich Ihren Schnappschuss bearbeiten möchten).

Wenn Sie eine ausführlichere Erklärung von Bare-Repos und einen weiteren Anwendungsbeispiel wünschen, habe ich hier einen Blog-Beitrag verfasst: https://stegosaurusdormant.com/bare-git-repo/

Greg Owen
quelle
4

Dies ist keine neue Antwort, aber es hat mir geholfen, die verschiedenen Aspekte der obigen Antworten zu verstehen (und es ist zu viel für einen Kommentar).

Mit Git Bash versuchen Sie einfach:

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/

Gleiches gilt für 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
quelle
2

$ git help repository-layout

Ein Git-Repository gibt es in zwei verschiedenen Varianten:

  • ein .git-Verzeichnis im Stammverzeichnis des Arbeitsbaums;
  • Ein .git-Verzeichnis, das ein nacktes Repository ist (dh ohne eigenen Arbeitsbaum), das normalerweise zum Austauschen von Historien mit anderen verwendet wird, indem es in dieses Repository verschoben und von dort abgerufen wird.
MichK
quelle