Git
Chapters ▾ 2nd Edition

1.3 Erste Schritte - Was ist Git?

Was ist Git?

Also, was ist Git in Kürze? Das ist ein wichtiger Teil, den es zu beachten gilt, denn wenn Sie verstehen, was Git und das grundlegenden Konzept seiner Arbeitsweise ist, dann wird die effektive Nutzung von Git für Sie wahrscheinlich viel einfacher sein. Wenn Sie Git erlernen, versuchen Sie, Ihren Kopf von den Dingen zu befreien, die Sie über andere VCSs wissen, wie CVS, Subversion oder Perforce – das wird Ihnen helfen, unangenehme Missverständnisse bei der Verwendung des Tools zu vermeiden. Auch wenn die Benutzeroberfläche von Git diesen anderen VCSs sehr ähnlich ist, speichert und betrachtet Git Informationen auf eine ganz andere Weise, und das Verständnis dieser Unterschiede hilft Ihnen Unklarheiten bei der Verwendung zu vermeiden.

Snapshots und nicht die Unterschiedes

Der Hauptunterschied zwischen Git und anderen Versionsverwaltungssystemen (insbesondere auch Subversion und vergleichbare Systeme) besteht in der Art und Weise wie Git die Daten betrachtet. Konzeptionell speichern die meisten anderen Systeme Informationen als eine Liste von dateibasierten Änderungen. Diese Systeme (CVS, Subversion, Perforce, Bazaar usw.) betrachten die Informationen, die sie verwalten, als eine Reihe von Dateien an denen im Laufe der Zeit Änderungen vorgenommen werden (dies wird allgemein als deltabasierte Versionskontrolle bezeichnet).

Storing data as changes to a base version of each file.
Figure 4. Speichern von Daten als Änderung an einzelnen Dateien auf Basis einer Ursprungsdatei.

Git arbeitet nicht auf diese Art und Weise. Stattdessen betrachtet Git seine Daten eher wie eine Reihe von Schnappschüssen eines Mini-Dateisystems. Git macht jedes Mal, wenn Sie den Status Ihres Projekts committen, das heißt den gegenwärtigen Status Ihres Projekts als eine Version in Git speichern, ein Abbild von all Ihren Dateien wie sie gerade aussehen und speichert einen Verweis in diesem Schnappschuss. Um dies möglichst effizient und schnell tun zu können, kopiert Git unveränderte Dateien nicht, sondern legt lediglich eine Verknüpfung zu der vorherigen Version der Datei an. Git betrachtet seine Daten eher wie einen Stapel von Schnappschüssen.

Git stores data as snapshots of the project over time.
Figure 5. Speichern der Daten-Historie eines Projekts in Form von Schnappschüssen.

Das ist ein wichtiger Unterschied zwischen Git und praktisch allen anderen Versionsverwaltungssystemen. In Git wurden daher fast alle Aspekte der Versionsverwaltung neu überdacht, die in anderen Systemen mehr oder weniger von ihrer jeweiligen Vorgängergeneration übernommen worden waren. Git arbeitet im Großen und Ganzen eher wie ein mit einigen unglaublich mächtigen Werkzeugen ausgerüstetes Mini-Dateisystem, statt nur als Versionsverwaltungssystem. Auf einige der Vorteile, die es mit sich bringt, Daten in dieser Weise zu verwalten, werden wir in Kapitel 3, Git Branching, eingehen, wenn wir das Git Branching Konzept kennenlernen.

Fast jede Funktion arbeitet lokal

Die meisten Aktionen in Git benötigen nur lokale Dateien und Ressourcen, um ausgeführt zu werden – im Allgemeinen werden keine Informationen von einem anderen Computer in Ihrem Netzwerk benötigt. Wenn Sie an ein CVCS gewöhnt sind, in dem die meisten Operationen diesen Netzwerk-Latenz-Overhead haben, wird Sie dieser Aspekt von Git denken lassen, dass die Götter der Geschwindigkeit Git mit außerirdischen Kräften gesegnet haben. Die allermeisten Operationen können nahezu ohne jede Verzögerung ausgeführt werden, da die vollständige Historie eines Projekts bereits auf dem jeweiligen Rechner verfügbar ist.

Um beispielsweise die Historie des Projekts zu durchsuchen, braucht Git sie nicht von einem externen Server zu holen – es liest diese einfach aus der lokalen Datenbank. Das heißt, die vollständige Projekthistorie ist ohne jede Verzögerung verfügbar. Wenn man sich die Änderungen einer aktuellen Version einer Datei im Vergleich zu vor einem Monat, anschauen möchte, dann kann Git den Stand von vor einem Monat in der lokalen Historie nachschlagen und einen lokalen Vergleich zur vorliegenden Datei durchführen. Für diesen Anwendungsfall benötigt Git keinen externen Server, weder um Dateien dort nachzuschlagen, noch um Unterschiede dort bestimmen zu lassen.

Das bedeutet natürlich außerdem, dass es fast nichts gibt, was man nicht tun kann, nur weil man gerade offline ist oder keinen Zugriff auf ein VPN hat. Wenn man also gerade im Flugzeug oder Zug ein wenig arbeiten will, kann man problemlos seine Arbeit einchecken und dann wenn man wieder mit einem Netzwerk verbunden ist, die Dateien auf einen Server hochladen. Wenn man zu Hause sitzt, aber der VPN Client gerade mal wieder nicht funktioniert, kann man immer noch arbeiten. Bei vielen anderen Systemen wäre dies unmöglich oder äußerst kompliziert umzusetzen. In Perforce können Sie beispielsweise nicht viel tun, wenn Sie nicht mit dem Server verbunden sind; in Subversion und CVS können Sie Dateien bearbeiten, aber Sie können keine Änderungen zu Ihren Daten übertragen (weil die Datenbank offline ist). Das scheint keine große Sache zu sein, aber Sie werden überrascht sein, was für einen großen Unterschied es machen kann.

Git stellt Integrität sicher

Von allen zu speichernden Daten berechnet Git Prüfsummen (engl. checksum) und speichert diese als Referenz zusammen mit den Daten ab. Das macht es unmöglich, dass sich Inhalte von Dateien oder Verzeichnissen ändern, ohne dass Git das mitbekommt. Git basiert auf dieser Funktionalität und sie ist ein integraler Teil der Git Philosophie. Man kann Informationen deshalb z.B. nicht während der Übermittlung verlieren oder unwissentlich beschädigte Dateien verwenden, ohne dass Git in der Lage wäre, dies festzustellen.

Der Mechanismus, den Git verwendet, um diese Prüfsummen zu erstellen, heißt SHA-1 Hash. Eine solche Prüfsumme ist eine 40 Zeichen lange Zeichenkette, die aus hexadezimalen Zeichen (0-9 und a-f) besteht und wird von Git aus den Inhalten einer Datei oder Verzeichnisstruktur berechnet. Ein SHA-1 Hash sieht wie folgt aus:

24b9da6552252987aa493b52f8696cd6d3b00373

Diese Hashes begegnen einem überall bei der Arbeit, weil sie so ausgiebig von Git genutzt werden. Tatsächlich speichert Git alles in seiner Datenbank nicht nach Dateinamen, sondern nach dem Hash-Wert seines Inhalts.

Git fügt im Regelfall nur Daten hinzu

Wenn Sie Aktionen in Git durchführen, werden fast alle von ihnen nur Daten zur Git-Datenbank hinzufügen. Deshalb ist es sehr schwer, das System dazu zu bewegen, irgendetwas zu tun, das nicht wieder rückgängig zu machen ist, oder dazu, Daten in irgendeiner Form zu löschen. Wie in jedem anderen VCS, kann man in Git Daten verlieren oder durcheinander bringen, solange man sie noch nicht eingecheckt hat. Aber sobald man einen Schnappschuss in Git eingecheckt hat, ist es sehr schwierig, diese Daten wieder zu verlieren, insbesondere wenn man regelmäßig seine lokale Datenbank auf ein anderes Repository hochlädt.

Unter anderem deshalb macht es so viel Spaß mit Git zu arbeiten. Man weiß genau, man kann ein wenig experimentieren, ohne befürchten zu müssen, irgendetwas zu zerstören oder durcheinander zu bringen. Wer sich genauer dafür interessiert, wie Git Daten speichert und wie man Daten, die scheinbar verloren sind, wiederherstellen kann, dem wird das Kapitel 2, Ungewollte Änderungen rückgängig machen, ans Herz gelegt..

Die drei Zustände

Jetzt heißt es aufgepasst! – Es folgt die wichtigste Information, die man sich merken muss, wenn man Git erlernen und dabei Fallstricke vermeiden will. Git definiert drei Hauptzustände, in denen sich eine Datei befinden kann: committet (engl. committed), geändert (engl. modified) und für Commit vorgemerkt (engl. staged).

  • Modified bedeutet, dass eine Datei geändert, aber noch nicht in die lokale Datenbank eingecheckt wurde.

  • Staged bedeutet, dass eine geänderte Datei in ihrem gegenwärtigen Zustand für den nächsten Commit vorgemerkt ist.

  • Committed bedeutet, dass die Daten sicher in der lokalen Datenbank gespeichert sind.

Das führt uns zu den drei Hauptbereichen eines Git-Projekts: dem Verzeichnisbaum, der sogenannten Staging-Area und dem Git-Verzeichnis.

Working tree, staging area, and Git directory.
Figure 6. Verzeichnisbaum, Staging-Area und Git-Verzeichnis.

Der Verzeichnisbaum ist ein einzelner Abschnitt einer Version des Projekts. Diese Dateien werden aus der komprimierten Datenbank im Git-Verzeichnis geholt und auf der Festplatte so abgelegt, damit Sie sie verwenden oder ändern können.

Die Staging-Area ist in der Regel eine Datei, die sich in Ihrem Git-Verzeichnis befindet und Informationen darüber speichert, was in Ihren nächsten Commit einfließen soll. Der technische Name im Git-Sprachgebrauch ist „Index“, aber der Ausdruck „Staging Area“ funktioniert genauso gut.

Im Git-Verzeichnis werden die Metadaten und die Objektdatenbank für Ihr Projekt gespeichert. Das ist der wichtigste Teil von Git, dieser Teil wird kopiert, wenn man ein Repository von einem anderen Rechner klont.

Der grundlegende Git-Arbeitsablauf sieht in etwa so aus:

  1. Sie ändern Dateien in Ihrem Verzeichnisbaum.

  2. Sie stellen selektiv Änderungen bereit, die Sie bei Ihrem nächsten Commit berücksichtigen möchten, wodurch nur diese Änderungen in den Staging-Bereich aufgenommen werden.

  3. Sie führen einen Commit aus, der die Dateien so übernimmt, wie sie sich in der Staging-Area befinden und diesen Snapshot dauerhaft in Ihrem Git-Verzeichnis speichert.

Wenn sich eine bestimmte Version einer Datei im Git-Verzeichnis befindet, wird sie als committed betrachtet. Wenn sie geändert und in die Staging-Area hinzugefügt wurde, gilt sie als für den Commit vorgemerkt (engl. staged). Und wenn sie geändert, aber noch nicht zur Staging-Area hinzugefügt wurde, gilt sie als geändert (engl. modified). Im Kapitel 2, Git Grundlagen, werden diese drei Zustände noch näher erläutert und wie man diese sinnvoll einsetzen kann oder alternativ, wie man den Zwischenschritt der Staging-Area überspringen kann.