Einführung in Git (Teil 1): Versionsverwaltung
Vorab: In diesem Artikel beschränken sich alle Git-Beispiele auf die Verwendung der Kommandozeile. Selbstverständlich gibt es auch grafische Clients für Git. Persönlich musste ich jedoch feststellen, dass aufgrund der ausgezeichneten Kommandozeilen-Tools von Git die meisten Aktionen von Git über die Kommandozeile tatsächlich am besten funktionieren.
Grundlagen der Versionskontrolle mit Git
Snapshot-basiertes SCM
Stellt euch zunächst einmal vor, Ihr wüsstet noch nichts von SCM-Systemen und würdet also ohne Versionskontrolle an einem Projekt arbeiten. Um trotzdem Zwischenstände eurer Arbeit sichern zu können, bietet es sich an, den Projektordner zwischendurch einfach immer wieder mal zu kopieren:
Auf diese Weise könnt Ihr sogar Änderungen zwischen euren Versionsständen nachvollziehen, indem ihr einfach den Unterschied zwischen beiden Verzeichnissen ermittelt. Das Unix-Tool „diff“ liefert hier beispielsweise gute Dienste:
Git funktioniert nach genau demselben Prinzip: Ein Versionsstand in Git (in Git-Sprech „Commit“ genannt) ist ein vollständiger Schnappschuss eures Projekts, in dem die vollständigen Inhalte aller Dateien gesichert werden. Um Speicherplatz zu sparen, speichert Git allerdings Dateien, die in mehreren Snapshots inhaltsgleich sind, nur einmal.
Dieses Snapshot-Prinzip ist einer der Haupt-Unterschiede von Git gegenüber anderen SCM-Systemen. Subversion speichert Änderungen beispielsweise im Delta-Format, das heißt ein Versionsstand in SVN (hier „Revision“ genannt) enthält nur die zeilenweisen Unterschiede zur Vorversion.
Dezentrales SCM
Ein weiterer Unterschied von Git gegenüber beispielsweise Subversion besteht darin, wo die Versionsgeschichte verwaltet wird. Bei zentralen SCM-Systemen wie Subversion und CVS ist die Versionsgeschichte auf einem Server gespeichert; auf dem lokalen Rechner des Anwenders liegt lediglich der aktuelle Versionsstand vor (die „Arbeitskopie“ oder „Working Copy“).
Bei dezentralen SCM-Systemen wie beispielsweise Git gibt es genau genommen keinen Server. Hier wird die komplette Versionsgeschichte lokal beim Client gespeichert. Dieser kann seine Versionsgeschichte dann optional mit denen auf anderen Rechnern abgleichen.
Installation
Installation unter Linux
Unter nahezu allen Linux-Distributionen könnt Ihr Git einfach über die integrierte Paketverwaltung herunterladen. Unter Ubuntu bzw. Debian reicht zum Beispiel einfach (jeweils mit sudo oder als root):
Installation unter MacOS
Falls Ihr XCode installiert habt, ist Git automatisch auf den System installiert. Alternativ könnt Ihr auch einen Installer auf der offiziellen Git-Webseite herunterladen. Als grafischen Client für MacOS kann ich außerdem Sourcetree empfehlen.
Installation unter Windows
Unter Windows gestaltet sich die Installation von Git ein klein wenig schwieriger. Gute Clients sind beispielsweise TortoiseGit, das auch für Windows verfügbare Sourcetree oder GitHub for Windows. Letzter bringt statt einer Bash-Shell zwar eine Powershell als Git-Kommandozeile mit, die Befehle bleiben allerdings die gleichen.
Konfiguration
Bevor Ihr mit der Nutzung beginnt, solltet Ihr Eure Git-Installation entsprechend konfigurieren. Je nachdem, wie Ihr „git config“ aufruft, werden eure Einstellungen entweder systemweit (unter Unix in der Datei /etc/gitconfig), für den jeweiligen Benutzer (im Benutzer-Verzeichnis unter ~/.gitconfig) oder pro Repository (dann in .git/config) gespeichert.
Beginnt damit, Git mitzuteilen, wer Ihr überhaupt seid:
Falls ihr einen alternativen Editor nutzen wollt (auf Unix-Systemen verwendet Git normalerweise den VI-Editor), könnt ihr euren bevorzugten Editor ebenfalls einstellen:
Andererseits: Wer sollte schon einen anderen Editor als VI verwenden wollen? ;)
Erste Schritte
Erstellen von Repositories
Ein neues Git-Repository kann mit dem Kommando „git init“ erstellt werden. Folgender Befehl erstellt ein neues Repository im aktuellen Verzeichnis:
Anschließend könnt Ihr in dem Verzeichnis bereits existierende Dateien dem Repository hinzufügen:
Wie die Sache mit dem „git commit“ im Detail funktioniert, erkläre ich später noch.
Commits und Dateizustände
Wie eingangs schon erwähnt, ist ein Git-Commit nichts anderes als ein Schnappschuss eines bestimmten Versionsstandes. Ein Commit zeichnet sich durch die folgenden Merkmale aus:
- Ein Commit hat eine sogenannte Commit-ID. Die Commit-ID ist eine 160 Bit lange kryptografische Prüfsumme des aktuellen Zustands des Repositories.
- Ein Commit hat in der Regel (Ausnahmen davon später) einen Vorgänger-Commit (den „Parent“-Commit).
- Ein Commit hat eine Commit-Message, die beschreibt, was in dem jeweiligen Commit geändert wurde.
- Ein Commit enthält außerdem ein Tree-Objekt, welches die im Repository enthaltenen Dateien beschreibt.
Jede Datei in einem Git-Repository kann mehrere Zustände annehmen. Grundsätzlich unterscheidet Git zunächst zwischen „verfolgten“ (tracked) und „nicht verfolgten“ (untracked) Dateien. Alle Dateien, die bereits im letzten Commit enthalten waren, gelten automatisch als verfolgt. Jede verfolgte Datei kann wiederum einen der folgenden Zustände annehmen:
- Unverändert (unmodified)
- Verändert (modified)
- Für den nächsten Commit vorgemerkt (staged)
Commits erzeugen
Den Zustand von Dateien könnt Ihr mit dem „git status“-Befehl überprüfen:
Wird nun eine neue Datei hinzugefügt, wird sie von Git zunächst als „untracked“ erkannt:
Mit dem Kommando „git add“ können Dateien (oder ganze Ordner) zur Versionskontrolle hinzugefügt werden:
Die so hinzugefügten Dateien sind zwar noch in keinem Commit erfasst, aber zumindest schon mal für den nächsten Commit vorgemerkt. Mit dem Befehl „git commit“ kann aus den Dateien in der Staging Area schließlich ein neuer Commit erstellt werden:
Die History betrachten
Mit dem Kommando „git log“ könnt Ihr anschließend Eure Versionsgeschichte betrachten. Unter Linux und MacOS könnt Ihr auch das zusammen mit Git ausgelieferte Programm „gitk“ verwenden, welches die History grafisch darstellt. Unter Windows bieten TortoiseGit und Sourcetree ähnliche Funktionen.
Um eine Kurzform der History auf der Kommandozeile auszugeben, könnt Ihr auch folgendes Kommando verwenden:
Mehr
Zum weiterführenden Lesen kann ich sehr das frei verfügbare Buch Pro Git empfehlen, welches auch als Inspiration für die meisten Abbildungen in diesem Artikel gedient hat. In ein paar weiterführenden Artikeln werde ich dann nochmal genau darauf eingehen, wie man in Git mit Zweigen und Repositories auf anderen Servern arbeiten kann.
Kommentare
Und wo finde ich Teil 2?
hier findest du Teil 2: https://www.mittwald.de/blog/webentwicklung-design/einfuhrung-in-git-teil-2-branching-und-merging
Viele Grüße
Kristina
Das Buch ProGit habe schon ganz gut durchgearbeitet, trotzdem habe ich bei ersten Versuchen noch Probleme Dateien von einem Test-Verzeichnis via Git in ein zweites Testverzeichnis zu transferieren. Hab schon viel verstanden, aber scheinbar noch nicht alles. Daher hoffe ich über eine zweite Beschreibung der Arbeitsweise noch ein wenig schlauer zu werden. Der Upstream-branch macht mir noch zu schaffen.