-
1. Erste Schritte
- 1.1 Über Versionskontrolle
- 1.2 Eine kurze Geschichte von Git
- 1.3 Was ist Git?
- 1.4 Die Kommandozeile
- 1.5 Git installieren
- 1.6 Erstmalige Git-Einrichtung
- 1.7 Hilfe bekommen
- 1.8 Zusammenfassung
-
2. Git Grundlagen
-
3. Git Branching
- 3.1 Branches im Überblick
- 3.2 Grundlegendes Branching und Merging
- 3.3 Branch-Management
- 3.4 Branching-Workflows
- 3.5 Remote-Branches
- 3.6 Rebasing
- 3.7 Zusammenfassung
-
4. Git auf dem Server
- 4.1 Die Protokolle
- 4.2 Git auf einem Server einrichten
- 4.3 Generieren Ihres SSH-Public-Keys
- 4.4 Einrichten des Servers
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Drittanbieter-Hosting-Optionen
- 4.10 Zusammenfassung
-
5. Verteiltes Git
-
6. GitHub
-
7. Git-Werkzeuge
- 7.1 Revisionsauswahl
- 7.2 Interaktives Staging
- 7.3 Stashing und Bereinigen
- 7.4 Ihre Arbeit signieren
- 7.5 Suchen
- 7.6 Historie umschreiben
- 7.7 Reset entmystifiziert
- 7.8 Fortgeschrittenes Merging
- 7.9 Rerere
- 7.10 Debugging mit Git
- 7.11 Submodule
- 7.12 Bundling
- 7.13 Ersetzen
- 7.14 Credential-Speicher
- 7.15 Zusammenfassung
-
8. Git anpassen
-
9. Git und andere Systeme
- 9.1 Git als Client
- 9.2 Migration zu Git
- 9.3 Zusammenfassung
-
10. Git-Interna
- 10.1 Plumbing und Porcelain
- 10.2 Git-Objekte
- 10.3 Git-Referenzen
- 10.4 Packfiles
- 10.5 Die Refspec
- 10.6 Übertragungsprotokolle
- 10.7 Wartung und Datenwiederherstellung
- 10.8 Umgebungsvariablen
- 10.9 Zusammenfassung
-
Anhang A: Git in anderen Umgebungen
- A1.1 Grafische Oberflächen
- A1.2 Git in Visual Studio
- A1.3 Git in Visual Studio Code
- A1.4 Git in IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git in Sublime Text
- A1.6 Git in Bash
- A1.7 Git in Zsh
- A1.8 Git in PowerShell
- A1.9 Zusammenfassung
-
Anhang B: Git in Ihre Anwendungen einbetten
- A2.1 Kommandozeilen-Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
Anhang C: Git-Befehle
- A3.1 Einrichtung und Konfiguration
- A3.2 Projekte abrufen und erstellen
- A3.3 Grundlegendes Snapshotting
- A3.4 Branching und Merging
- A3.5 Projekte teilen und aktualisieren
- A3.6 Inspektion und Vergleich
- A3.7 Debugging
- A3.8 Patching
- A3.9 E-Mail
- A3.10 Externe Systeme
- A3.11 Administration
- A3.12 Plumbing-Befehle
3.1 Git-Branching - Branches im Überblick
Fast jedes VCS hat eine Form der Branching-Unterstützung. Branching bedeutet, dass Sie von der Hauptentwicklungslinie abweichen und Ihre Arbeit fortsetzen, ohne die Hauptlinie zu beeinträchtigen. In vielen VCS-Tools ist dies ein eher kostspieliger Prozess, der oft das Erstellen einer neuen Kopie Ihres Quellcodeverzeichnisses erfordert, was bei großen Projekten lange dauern kann.
Manche Leute bezeichnen das Branching-Modell von Git als sein „Killer-Feature", und es unterscheidet Git sicherlich von anderen VCS-Tools. Warum ist es so besonders? Die Art und Weise, wie Git Branches erstellt, ist unglaublich leichtgewichtig, was Branching-Operationen fast augenblicklich macht und das Hin- und Herwechseln zwischen Branches generell ebenso schnell ermöglicht. Im Gegensatz zu vielen anderen VCSs fördert Git Workflows, bei denen häufig gebrancht und zusammengeführt wird, sogar mehrmals am Tag. Das Verständnis und die Beherrschung dieser Funktion geben Ihnen ein leistungsfähiges und einzigartiges Werkzeug an die Hand und können die Art und Weise, wie Sie entwickeln, grundlegend verändern.
Branches im Überblick
Um die Funktionsweise von Git-Branching wirklich zu verstehen, müssen wir einen Schritt zurücktreten und untersuchen, wie Git seine Daten speichert.
Wie Sie sich vielleicht aus Was ist Git? erinnern, speichert Git Daten nicht als eine Reihe von Changesets oder Unterschieden, sondern stattdessen als eine Reihe von Snapshots.
Wenn Sie einen Commit erstellen, speichert Git ein Commit-Objekt, das einen Zeiger auf den Snapshot des Inhalts enthält, den Sie vorbereitet haben. Dieses Objekt enthält auch den Namen und die E-Mail-Adresse des Autors, die von Ihnen eingegebene Nachricht und Zeiger auf den Commit oder die Commits, die direkt vor diesem Commit kamen (sein Elternteil oder seine Eltern): Null Eltern für den initialen Commit, ein Elternteil für einen normalen Commit und mehrere Eltern für einen Commit, der aus dem Zusammenführen von zwei oder mehr Branches resultiert.
Um dies zu visualisieren, nehmen wir an, Sie haben ein Verzeichnis mit drei Dateien, und Sie bereiten sie alle vor und committen sie. Das Vorbereiten der Dateien berechnet einen Checksummenwert für jede Datei (den SHA-1-Hash, den wir in Was ist Git? erwähnt haben), speichert diese Version der Datei im Git-Repository (Git nennt sie Blobs) und fügt diesen Checksummenwert dem Staging-Bereich hinzu.
$ git add README test.rb LICENSE
$ git commit -m 'Initial commit'
Wenn Sie den Commit erstellen, indem Sie git commit ausführen, berechnet Git die Checksumme für jedes Unterverzeichnis (in diesem Fall nur das Hauptprojektverzeichnis) und speichert diese als Baumobjekt im Git-Repository. Git erstellt dann ein Commit-Objekt, das die Metadaten und einen Zeiger auf den Hauptprojektbaum enthält, damit es diesen Snapshot bei Bedarf wiederherstellen kann.
Ihr Git-Repository enthält nun fünf Objekte: drei Blobs (jeder repräsentiert den Inhalt einer der drei Dateien), einen Baum, der die Inhalte des Verzeichnisses auflistet und angibt, welche Dateinamen als welche Blobs gespeichert sind, und einen Commit mit dem Zeiger auf diesen Hauptbaum und allen Commit-Metadaten.
Wenn Sie einige Änderungen vornehmen und erneut committen, speichert der nächste Commit einen Zeiger auf den Commit, der unmittelbar davor kam.
Ein Branch in Git ist einfach ein leichtgewichtiger, beweglicher Zeiger auf einen dieser Commits. Der Standard-Branchname in Git ist master. Wenn Sie beginnen, Commits zu erstellen, erhalten Sie einen master-Branch, der auf den letzten von Ihnen erstellten Commit zeigt. Jedes Mal, wenn Sie committen, bewegt sich der master-Branch-Zeiger automatisch vorwärts.
|
Hinweis
|
Der „master“-Branch in Git ist kein spezieller Branch. Er ist genau wie jeder andere Branch. Der einzige Grund, warum fast jedes Repository einen hat, ist, dass der Befehl |
Einen neuen Branch erstellen
Was passiert, wenn Sie einen neuen Branch erstellen? Nun, das Erstellen eines neuen Branches erstellt einen neuen Zeiger, den Sie bewegen können. Nehmen wir an, Sie möchten einen neuen Branch namens testing erstellen. Dies tun Sie mit dem Befehl git branch.
$ git branch testing
Dies erstellt einen neuen Zeiger auf denselben Commit, auf dem Sie sich gerade befinden.
Woher weiß Git, auf welchem Branch Sie sich gerade befinden? Es verwaltet einen speziellen Zeiger namens HEAD. Beachten Sie, dass dies sich stark von dem Konzept von HEAD in anderen VCSs unterscheidet, die Sie vielleicht gewohnt sind, wie Subversion oder CVS. In Git ist dies ein Zeiger auf den lokalen Branch, auf dem Sie sich gerade befinden. In diesem Fall sind Sie immer noch auf master. Der Befehl git branch hat nur einen neuen Branch erstellt – er hat nicht zu diesem Branch gewechselt.
Sie können dies leicht sehen, indem Sie einen einfachen Befehl git log ausführen, der Ihnen zeigt, worauf die Branch-Zeiger zeigen. Diese Option heißt --decorate.
$ git log --oneline --decorate
f30ab (HEAD -> master, testing) Add feature #32 - ability to add new formats to the central interface
34ac2 Fix bug #1328 - stack overflow under certain conditions
98ca9 Initial commit
Sie sehen die Branches master und testing, die sich direkt neben dem Commit f30ab befinden.
Branches wechseln
Um zu einem vorhandenen Branch zu wechseln, führen Sie den Befehl git checkout aus. Wechseln wir zum neuen testing-Branch.
$ git checkout testing
Dies verschiebt HEAD, sodass es auf den testing-Branch zeigt.
Was ist die Bedeutung davon? Nun, machen wir einen weiteren Commit.
$ vim test.rb
$ git commit -a -m 'Make a change'
Das ist interessant, denn jetzt hat sich Ihr testing-Branch vorwärts bewegt, aber Ihr master-Branch zeigt immer noch auf den Commit, auf dem Sie sich befanden, als Sie git checkout ausgeführt haben, um den Branch zu wechseln. Wechseln wir zurück zum master-Branch.
$ git checkout master
|
Hinweis
|
git log zeigt nicht immer alle Branches anWenn Sie jetzt Der Branch ist nicht verschwunden; Git weiß einfach nicht, dass Sie an diesem Branch interessiert sind, und versucht, Ihnen zu zeigen, wofür es hält, dass Sie sich interessieren. Mit anderen Worten, standardmäßig zeigt Um die Commit-Historie für den gewünschten Branch anzuzeigen, müssen Sie ihn explizit angeben: |
Dieser Befehl hat zwei Dinge getan. Er hat den HEAD-Zeiger zurückbewegt, um auf den master-Branch zu zeigen, und er hat die Dateien in Ihrem Arbeitsverzeichnis auf den Snapshot zurückgesetzt, auf den master zeigt. Das bedeutet auch, dass die Änderungen, die Sie von diesem Zeitpunkt an vornehmen, von einer älteren Version des Projekts abweichen werden. Es spult im Wesentlichen die Arbeit zurück, die Sie in Ihrem testing-Branch geleistet haben, damit Sie eine andere Richtung einschlagen können.
|
Hinweis
|
Das Wechseln von Branches ändert Dateien in Ihrem Arbeitsverzeichnis
Es ist wichtig zu beachten, dass sich Dateien in Ihrem Arbeitsverzeichnis ändern, wenn Sie in Git die Branches wechseln. Wenn Sie zu einem älteren Branch wechseln, wird Ihr Arbeitsverzeichnis auf den Zustand zurückgesetzt, den es beim letzten Commit auf diesem Branch hatte. Wenn Git dies nicht sauber durchführen kann, wird es Ihnen den Wechsel überhaupt nicht erlauben. |
Machen wir ein paar Änderungen und committen wir erneut.
$ vim test.rb
$ git commit -a -m 'Make other changes'
Jetzt hat sich Ihre Projekt-Historie aufgespalten (siehe Aufgespaltene Historie). Sie haben einen Branch erstellt und zu ihm gewechselt, einige Arbeiten daran ausgeführt und dann zu Ihrem Hauptbranch zurückgewechselt und andere Arbeiten erledigt. Beide Änderungen sind in separaten Branches isoliert: Sie können zwischen den Branches hin- und herwechseln und sie zusammenführen, wenn Sie bereit sind. Und das alles haben Sie mit einfachen Befehlen branch, checkout und commit erledigt.
Sie können dies auch leicht mit dem Befehl git log sehen. Wenn Sie git log --oneline --decorate --graph --all ausführen, wird die Historie Ihrer Commits ausgegeben, wobei angezeigt wird, worauf Ihre Branch-Zeiger zeigen und wie sich Ihre Historie aufgespalten hat.
$ git log --oneline --decorate --graph --all
* c2b9e (HEAD, master) Make other changes
| * 87ab2 (testing) Make a change
|/
* f30ab Add feature #32 - ability to add new formats to the central interface
* 34ac2 Fix bug #1328 - stack overflow under certain conditions
* 98ca9 Initial commit of my project
Da ein Branch in Git tatsächlich eine einfache Datei ist, die die 40 Zeichen lange SHA-1-Prüfsumme des Commits enthält, auf den sie zeigt, sind Branches günstig zu erstellen und zu löschen. Das Erstellen eines neuen Branches ist so schnell und einfach wie das Schreiben von 41 Bytes in eine Datei (40 Zeichen und ein Zeilenumbruch).
Dies steht in scharfem Gegensatz dazu, wie die meisten älteren VCS-Tools verzweigen, was das Kopieren aller Projektdateien in ein zweites Verzeichnis beinhaltet. Dies kann je nach Projektgröße Sekunden oder sogar Minuten dauern, während es in Git immer augenblicklich ist. Da wir die Eltern beim Committen aufzeichnen, wird die Ermittlung einer geeigneten Merge-Basis zum Zusammenführen automatisch für uns erledigt und ist im Allgemeinen sehr einfach. Diese Funktionen fördern die häufige Erstellung und Nutzung von Branches durch Entwickler.
Mal sehen, warum Sie das tun sollten.
|
Hinweis
|
Einen neuen Branch erstellen und gleichzeitig zu ihm wechseln
Es ist üblich, einen neuen Branch zu erstellen und sofort zu diesem neuen Branch wechseln zu wollen – dies kann in einem einzigen Vorgang mit |
|
Hinweis
|
Ab Git Version 2.23 können Sie
|