Was ist der Unterschied zwischen "git init" und "git init --bare"?

162

Was ist der Unterschied zwischen git initund git init --bare? Ich fand, dass viele Blog-Beiträge --barefür ihren Git-Server erforderlich sind ?

Von der Manpage stand:

--bare

Erstellen Sie ein nacktes Repository. Wenn die GIT_DIR-Umgebung nicht festgelegt ist, wird sie auf das aktuelle Arbeitsverzeichnis festgelegt

Aber was bedeutet das eigentlich? Ist es --barefür das Git-Server-Setup erforderlich ?

Kit Ho
quelle

Antworten:

143

Non-Bare Git Repo

Diese Variante erstellt ein Repository mit einem Arbeitsverzeichnis, damit Sie tatsächlich arbeiten können ( git clone). Nach dem Erstellen sehen Sie, dass das Verzeichnis einen .git-Ordner enthält, in dem der Verlauf und alle Git-Installationen gespeichert sind. Sie arbeiten auf der Ebene, auf der sich der Ordner .git befindet.

Nacktes Git Repo

Die andere Variante erstellt ein Repository ohne Arbeitsverzeichnis ( git clone --bare). Sie erhalten kein Verzeichnis, in dem Sie arbeiten können. Alles im Verzeichnis ist jetzt das, was im obigen Fall im Ordner .git enthalten war.

Warum Sie eins gegen das andere verwenden würden

Die Notwendigkeit für Git-Repos ohne Arbeitsverzeichnis ist die Tatsache, dass Sie Zweige dorthin verschieben können und es nicht verwaltet, woran jemand arbeitet. Sie können weiterhin auf ein nicht nacktes Repository pushen, werden jedoch abgelehnt, da Sie möglicherweise einen Zweig verschieben können, an dem jemand in diesem Arbeitsverzeichnis arbeitet.

In einem Projekt ohne Arbeitsordner können Sie die Objekte also nur so sehen, wie Git sie speichert. Sie werden komprimiert und serialisiert und unter dem SHA1 (einem Hash) ihres Inhalts gespeichert. Um ein Objekt in ein nacktes Repository zu bekommen, müssen Sie git showden sha1 des Objekts angeben, das Sie sehen möchten. Sie werden keine Struktur sehen, wie Ihr Projekt aussieht.

Bloße Repositorys sind normalerweise zentrale Repositorys, in die jeder seine Arbeit verlagert. Es besteht keine Notwendigkeit, die eigentliche Arbeit zu manipulieren. Auf diese Weise können Sie die Bemühungen zwischen mehreren Personen synchronisieren. Sie können Ihre Projektdateien nicht direkt anzeigen.

Möglicherweise benötigen Sie keine nackten Repositorys, wenn Sie der einzige sind, der an dem Projekt arbeitet, oder wenn Sie kein "logisch zentrales" Repository möchten / benötigen. Man würde es vorziehen , git pull von den anderen Repositories in diesem Fall. Dies vermeidet die Einwände, die git beim Verschieben in nicht nackte Repositorys hat.

Hoffe das hilft

Adam Dymitruk
quelle
Behalte das , wirf ein aus dieser Linie raus - Einer würde es vorziehen, von einem anderen zu ziehen ... :-)
Arup Rakshit
10
Ich finde diese Antwort sehr unklar und verwirrend. Einige der Gründe sind hier: meta.stackoverflow.com/questions/339837/…
Marko Avlijaš
Bare repositories are usually central repositories where everyone moves their work to.Wollen Sie damit sagen, dass ein nacktes Repository die Quelle ist, aus der andere Projektmitarbeiter ein Projekt klonen können? Das heißt, Mitarbeiter behandeln dies als das remote?
Minh Tran
111

Kurze Antwort

Ein nacktes Repository ist ein Git-Repository ohne Arbeitskopie. Daher ist der Inhalt von .git für dieses Verzeichnis die oberste Ebene.

Verwenden Sie ein nicht nacktes Repository, um lokal zu arbeiten, und ein nacktes Repository als zentralen Server / Hub, um Ihre Änderungen für andere Personen freizugeben. Wenn Sie beispielsweise ein Repository auf github.com erstellen, wird es als nacktes Repository erstellt.

Also, in Ihrem Computer:

git init
touch README
git add README
git commit -m "initial commit"

auf dem Server:

cd /srv/git/project
git init --bare

Dann drücken Sie auf dem Client:

git push username@server:/srv/git/project master

Sie können sich dann die Eingabe sparen, indem Sie sie als Fernbedienung hinzufügen.

Das Repository auf der Serverseite erhält Commits per Pull und Push und nicht durch Bearbeiten von Dateien und anschließendes Festschreiben auf dem Server. Daher handelt es sich um ein reines Repository.

Einzelheiten

Sie können auf ein Repository pushen, das kein nacktes Repository ist, und git stellt fest, dass es dort ein .git-Repository gibt. Da die meisten "Hub" -Repositorys jedoch keine Arbeitskopie benötigen, ist es normal, ein nacktes Repository für zu verwenden es und empfohlen, da es keinen Sinn macht, eine Arbeitskopie in dieser Art von Repositories zu haben.

Wenn Sie jedoch in ein nicht nacktes Repository pushen, wird die Arbeitskopie inkonsistent, und git warnt Sie:

remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.

Sie können diese Warnung überspringen. Die empfohlene Einrichtung lautet jedoch: Verwenden Sie ein nicht nacktes Repository, um lokal zu arbeiten, und ein nacktes Repository als Hub oder zentralen Server, um Push- und Pull-Vorgänge durchzuführen.

Wenn Sie die Arbeit direkt mit der Arbeitskopie eines anderen Entwicklers teilen möchten, können Sie Repositorys voneinander abrufen, anstatt zu pushen.

Duncan
quelle
Wenn ich mein Projekt auf dem Git-Server bearbeiten möchte, ist es nicht erforderlich, die Option --bare zu haben, nicht wahr?
Kit Ho
Sie verwenden bare für das Remote-Repository, nicht für das lokale.
Duncan
Es ist eine Weile, aber hier noch eine Frage. Wenn wir ein nacktes Remote-Repository haben, kann jeder Entwickler einen Push darauf ziehen, und das Repository ist ein "zentrales". Wenn wir jedoch ohne ein reines Repository arbeiten, sollten die Entwickler nur voneinander abziehen, aber niemals pushen. Das letzte Szenario ist einfach gut, wenn es nur 2 Arbeitskopien des Repos gibt (auch bekannt als lokale Repos). Ist das richtig?
Asturio
60

Als ich diese Frage vor einiger Zeit las, war alles für mich verwirrend. Ich habe gerade angefangen, Git zu verwenden, und es gibt diese Arbeitskopien (was zu diesem Zeitpunkt nichts bedeutete). Ich werde versuchen, dies aus der Perspektive des Typen zu erklären, der gerade mit git angefangen hat, ohne eine Ahnung von Terminologie zu haben.

Ein schönes Beispiel für die Unterschiede kann folgendermaßen beschrieben werden :

--baregibt Ihnen nur einen Speicherplatz (Sie können dort nicht entwickeln). Ohne --barees gibt Ihnen die Möglichkeit, sich dort zu entwickeln (und einen Speicherplatz zu haben).

git initErstellt ein Git-Repository aus Ihrem aktuellen Verzeichnis. Es fügt den Ordner .git hinzu und ermöglicht das Starten Ihres Revisionsverlaufs.

git init --bareErstellt auch ein Repository, verfügt jedoch nicht über das Arbeitsverzeichnis. Dies bedeutet, dass Sie keine Dateien bearbeiten, Ihre Änderungen festschreiben oder neue Dateien in diesem Repository hinzufügen können.

Wann --barekann hilfreich sein? Sie und einige andere arbeiten an dem Projekt und verwenden Git. Sie haben das Projekt auf einem Server gehostet ( amazon ec2). Jeder von Ihnen hat seinen eigenen Computer und Sie geben Ihren Code weiter ec2. Keiner von Ihnen entwickelt tatsächlich etwas ec2(Sie verwenden Ihre Maschinen) - Sie drücken einfach Ihren Code. Sie ec2sind also nur ein Speicher für Ihren gesamten Code und sollten wie --barealle Ihre Computer ohne erstellt werden --bare(höchstwahrscheinlich nur einer, und der andere klont einfach alles). Der Workflow sieht folgendermaßen aus:

Geben Sie hier die Bildbeschreibung ein

Salvador Dali
quelle
1
Wir könnten also sagen, dass wir mit einem --bare Repository eine Art Client-Server-Architektur erstellen können, wie dies bei Subversion der Fall ist.
Emiliano Sangoi
14

Ein Standard-Git-Repository setzt voraus, dass Sie es als Arbeitsverzeichnis verwenden. Wenn Sie sich auf einem Server befinden, benötigen Sie normalerweise kein Arbeitsverzeichnis. Nur das Repository. In diesem Fall sollten Sie die --bareOption verwenden.

Sandro Munda
quelle
in einem Repo mit der Option --bare, sodass wir nicht die gesamte Projektdatei sehen können? Es scheint, dass ich alle meine Projektdateien mit --bare Option verliere ..
Kit Ho
11

Ein nicht nacktes Repository ist die Standardeinstellung. Es ist das, was beim Ausführen erstellt git initwird oder was Sie beim Klonen erhalten (ohne dasbare Option) von einem Server .

Wenn Sie mit einem solchen Repository arbeiten, können Sie alle Dateien im Repository anzeigen und bearbeiten. Wenn Sie mit dem Repository interagieren - beispielsweise durch Festschreiben einer Änderung - speichert Git Ihre Änderungen in einem versteckten Verzeichnis namens.git .

Wenn Sie einen Git-Server haben, müssen keine Arbeitskopien der Dateien vorhanden sein. Sie benötigen lediglich die Git-Daten, die in gespeichert sind .git. Ein nacktes Repository ist genau das.git Verzeichnis ohne Arbeitsbereich zum Ändern und Festschreiben von Dateien.

Wenn Sie von einem Server klonen, verfügt Git über alle Informationen im .gitVerzeichnis, die zum Erstellen Ihrer Arbeitskopie erforderlich sind .

Andrew
quelle
1

Ein weiterer Unterschied zwischen --bare und Working Tree-Repositorys besteht darin, dass im ersten Fall keine verlorenen Commits gespeichert werden, sondern nur Commits, die zu einer Verzweigungsspur gehören. Auf der anderen Seite behält Working Tree alle Commits für immer bei. Siehe unten...

Ich habe das erste Repository (Name: git-bare ) mit erstellt git init --bare. Es ist der Server. Es befindet sich auf der linken Seite, wo es keine Remote-Zweige gibt, da dies das Remote-Repository selbst ist.

Ich habe das zweite Repository (Name: Git-Working-Tree ) mit git clonedem ersten erstellt. Es ist auf der rechten Seite. Es verfügt über lokale Zweigstellen, die mit Remote-Zweigstellen verbunden sind.

(Die Texte 'erster', 'zweiter', 'dritter', 'vierter', 'alpha', 'beta' und 'delta' sind die Commit-Kommentare. Die Namen 'master' und 'greek' sind Zweignamen.)

Lokale und Remote-Repositorys

Jetzt werde ich den Zweig mit dem Namen 'griechisch' sowohl in git-bare (Befehl :)git push --delete origin greek als auch lokal in git-working-tree (Befehl :) löschen git branch -D greek. So sieht der Baum aus:

Das git-bare-Repository löscht das, worauf nicht mehr verwiesen wird

Das git-bare- Repository löscht sowohl den Zweig als auch alle referenzierten Komits. Auf dem Bild sehen wir, dass sein Baum aus diesem Grund reduziert wurde.

Auf der anderen Seite löscht das Git-Working-Tree- Repository, das einem häufig verwendeten lokalen Repository entspricht, keine Commits, auf die jetzt nur noch direkt von Ihrem Hash mit einem git checkout 7fa897b7Befehl verwiesen werden kann . Deshalb hat sein Baum keine modifizierte Struktur.

KURZDARSTELLUNG: Commits werden niemals in Arbeitsbaum- Repositorys gelöscht, sondern in bloßen Repositorys gelöscht .

In der Praxis können Sie einen gelöschten Zweig auf dem Server nur wiederherstellen, wenn er in einem lokalen Repository vorhanden ist.

Es ist jedoch sehr seltsam, dass die Größe des Bare- Repositorys nach dem Löschen eines Remote-Zweigs nicht an Festplattengröße abnimmt. Das heißt, die Dateien sind irgendwie immer noch da. Verwenden Sie den git gc --pruneBefehl, um das Repository zu löschen, indem Sie löschen, auf was nicht mehr verwiesen wird oder auf was nie verwiesen werden kann (letzterer Fall)

Sergio Cabral
quelle
Um Git-Befehle zu testen, versuchen Sie: github.com/sergiocabral/App.GitPlayground
Sergio Cabral