Ich habe also in letzter Zeit gelesen, wie man einen Git-Server einrichtet, und nachdem ich festgestellt habe, dass überhaupt kein spezifischer Daemon benötigt wird (nur ein SSH-Server mit einem Dateisystem dahinter), habe ich mehr über git nachgedacht verwaltet Dateien unter der Haube.
Die Strategie, wie jedes Commit innerhalb des .objects-Ordners dargestellt wird und wie alles zusammenpasst, ist ziemlich clever, aber es scheint nicht explizit erwähnt zu werden, dass dieser Ansatz es tatsächlich ermöglicht, git auf sehr einfache Weise Parallelität zu erreichen, ohne Notwendigkeit eines Signalisierungsservers.
Nichtsdestoweniger gibt es Situationen, in denen Nebenläufigkeit nicht garantiert werden kann, was im Grunde ist, wenn Geschichte neu geschrieben wird (forcierte Pushs). Wird in diesem Fall eine Sperrstrategie in der Struktur verwendet, um Nebenläufigkeitsprobleme zu vermeiden? Gibt es zu diesem Thema mehr Dokumentation?
(Etwas zu diesem Thema wird in diese SO Antwort , aber nur sehr kurz.)
Die git-Datenstrukturen sind unveränderlich, außer refs (d. h. branches / tags / etc), und "rewriting history" ist nicht sehr korrekter Begriff, passender "creating alternative history". Das Repo wird alle Objekte haben - neu und alt. Darüber hinaus werden alle Änderungen, die in einem lokalen Repository während "Push" -Objekten erstellt werden, nur übertragen. Dann drücken Sie es, es sendet alle Objekte zuerst (und weil Objekte durch ihren Inhalt definiert sind, sind sie eindeutig, es gibt kein Nebenläufigkeitsproblem). Nachdem alle Objekte gesendet wurden, ändert sich eine Referenz. Es ist nur eine winzige einzelne Datei ( refs/heads/<branchName>
), die mit 40 Byte sha1-Schlüssel überschrieben werden soll. Wie ich weiß, macht es eine atomare Compare-and-Set-Änderung der Datei. Es liest den alten Ref-Wert, erstellt eine Sperrdatei, prüft, ob der alte Wert unverändert ist, ersetzt ihn durch new sha1 und löscht die Sperre. Wenn es fehlschlägt, schlägt der Push fehl, und Sie müssen es erneut versuchen (d. H. Optimistische Sperre). Sie könnten mehr Details aus dem Quellcode , update_ref-Funktion herausfinden.
Nach dem force-push können einige "lose Objekte" erscheinen (d. h. Objekte, auf die von keinem vorhandenen Verweis Bezug genommen wird), so dass diese Objekte später als Müll gesammelt werden.
Sehr schlau und ordentlich.
Bei Bedarf werden verschiedene Dateien erstellt, die als Sperren dienen. Git erstellt eine Datei mit dem Namen .git/index.lock
, um den Index zu sperren. git index-pack
kann eine Datei .keep
erstellen, um eine Wettlaufsituation zu verhindern. Es kann mehr Beispiele geben.
Tags und Links git concurrency git-push git-filter-branch