-
1. Erste Schritte
-
2. Git Grundlagen
-
3. Git Branching
- 3.1 Branches auf einen Blick
- 3.2 Einfaches 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 Erstellung eines SSH-Public-Keys
- 4.4 Einrichten des Servers
- 4.5 Git-Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Von Drittanbietern gehostete Optionen
- 4.10 Zusammenfassung
-
5. Verteiltes Git
-
6. GitHub
-
7. Git Tools
- 7.1 Revisions-Auswahl
- 7.2 Interactive Staging
- 7.3 Stashing and Cleaning
- 7.4 Ihre Arbeit signieren
- 7.5 Suchen
- 7.6 Rewriting History
- 7.7 Reset Demystified
- 7.8 Fortgeschrittenes Merging
- 7.9 Rerere
- 7.10 Debugging with Git
- 7.11 Submodules
- 7.12 Bundling
- 7.13 Replace
- 7.14 Anmeldeinformationen speichern
- 7.15 Zusammenfassung
-
8. Git einrichten
- 8.1 Git Konfiguration
- 8.2 Git-Attribute
- 8.3 Git Hooks
- 8.4 Beispiel für Git-forcierte Regeln
- 8.5 Zusammenfassung
-
9. Git und andere Systeme
- 9.1 Git als Client
- 9.2 Migration zu Git
- 9.3 Zusammenfassung
-
10. Git Interna
-
A1. Appendix A: Git in Other Environments
- A1.1 Graphical Interfaces
- A1.2 Git in Visual Studio
- A1.3 Git in Visual Studio Code
- A1.4 Git in Eclipse
- A1.5 Git in Sublime Text
- A1.6 Git in Bash
- A1.7 Git in Zsh
- A1.8 Git in PowerShell
- A1.9 Summary
-
A2. Appendix B: Embedding Git in your Applications
- A2.1 Command-line Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Appendix C: Git Kommandos
- A3.1 Setup und Konfiguration
- A3.2 Projekte importieren und erstellen
- A3.3 Einfache Snapshot-Funktionen
- A3.4 Branching und Merging
- A3.5 Sharing and Updating Projects
- A3.6 Inspection and Comparison
- A3.7 Debugging
- A3.8 Patching
- A3.9 Email
- A3.10 External Systems
- A3.11 Administration
- A3.12 Plumbing Commands
3.2 Git Branching - Einfaches Branching und Merging
Einfaches Branching und Merging
Lassen Sie uns ein einfaches Beispiel für das Verzweigen und Zusammenführen (engl. branching and merging) anschauen, wie es Ihnen in einem praxisnahen Workflow begegnen könnte. Führen Sie diese Schritte aus:
-
Arbeiten Sie an einer Website
-
Erstellen Sie einen Branch für eine neue Anwendergeschichte, an der Sie gerade arbeiten
-
Erledigen Sie einige Arbeiten in diesem Branch
In diesem Moment erhalten Sie einen Anruf, dass ein anderes Problem kritisch ist und Sie einen Hotfix benötigen. Dazu werden Sie folgendes machen:
-
Wechseln Sie zu Ihrer Produktions-Branch
-
Erstellen Sie einen Branch, um den Hotfix einzufügen
-
Nachdem der Test abgeschlossen ist, mergen Sie den Hotfix-Branch und schieben ihn in die Produktions-Branch
-
Wechseln Sie zurück zu Ihrer ursprünglichen Anwenderstory und arbeiten Sie daran weiter
Einfaches Branching
Lassen Sie uns zunächst annehmen, Sie arbeiten an Ihrem Projekt und haben bereits ein paar Commits in Ihre master
-Branch gemacht.

Sie haben sich dafür entschieden, an „Issue #53“ zu arbeiten aus irgendeinem Fehlerverfolgunssystem, das Ihre Firma benutzt.
Um einen neuen Branch anzulegen und gleichzeitig zu diesem zu wechseln, können Sie die Anweisung git checkout
zusammen mit der Option -b
ausführen:
$ git checkout -b iss53
Switched to a new branch "iss53"
Das ist die Kurzform der beiden folgenden Befehle:
$ git branch iss53
$ git checkout iss53

Sie arbeiten an Ihrer Website und führen einige Commits durch.
Sobald Sie das machen, bewegt das den iss53
-Branch vorwärts, weil Sie in ihn gewechselt (engl. checked out) haben. Das bedeutet, Ihr HEAD
zeigt auf diesen Branch:
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'

iss53
-Branch hat sich bei Ihrer Arbeit vorwärts bewegtJetzt bekommen Sie einen Anruf, dass es ein Problem mit der Website gibt und Sie es umgehend beheben müssen.
Bei Git müssen Sie Ihren Fix nicht zusammen mit den Änderungen bereitstellen, die Sie bereits an iss53
vorgenommen haben, und Sie müssen auch keinen großen Aufwand damit betreiben, diese Änderungen rückgängig zu machen, bevor Sie daran arbeiten können, Ihren Fix auf das anzuwenden, was sich in der Produktionsumgebung befindet.
Alles, was Sie machen müssen, ist, zu Ihrem master
-Branch zurück zu wechseln.
Beachten Sie dabei, dass Git das Wechseln zu einer anderen Branch blockiert, falls Ihr Arbeitsverzeichnis oder Ihr Staging-Bereich nicht committete Modifikationen enthält, die Konflikte verursachen.
Es ist am besten, einen sauberen Zustand des Arbeitsbereichs anzustreben, bevor Sie die Zweige wechseln.
Es gibt Möglichkeiten, das zu umgehen (nämlich das Verstecken/Stashen und Revidieren/Amending von Änderungen), die wir später in Kapitel 7 Git Stashing behandeln werden.
Lassen Sie uns vorerst annehmen, Sie haben für alle Ihre Änderungen Commits durchgeführt, sodass Sie zu Ihrem master
-Branch zurück wechseln können.
$ git checkout master
Switched to branch 'master'
Zu diesem Zeitpunkt befindet sich das Arbeitsverzeichnis des Projektes in exakt dem gleichen Zustand, in dem es sich befand, bevor Sie mit der Arbeit an „Issue #53“ begonnen haben und Sie können sich direkt auf den Hotfix konzentrieren. Das ist ein wichtiger Punkt, den Sie unbedingt beachten sollten: Wenn Sie die Branches wechseln, setzt Git Ihr Arbeitsverzeichnis zurück, um so auszusehen, wie es das letzte Mal war, als Sie in den Branch committed haben. Dateien werden automatisch hinzugefügt, entfernt und verändert, um sicherzustellen, dass Ihre Arbeitskopie auf dem selben Stand ist wie zum Zeitpunkt Ihres letzten Commits auf diesem Branch.
Als Nächstes müssen Sie sich um den Hotfix kümmern.
Lassen Sie uns einen hotfix
-Branch erstellen, an dem Sie bis zu dessen Fertigstellung arbeiten:
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
1 file changed, 2 insertions(+)

master
-Branch basierender hotfix-BranchSie können Ihre Tests durchführen, sich vergewissern, dass der Hotfix das macht, was Sie von ihm erwarten und schließlich den Branch hotfix
wieder in Ihren master
-Zweig integrieren (engl. merge), um ihn in der Produktion einzusetzen.
Das machen Sie mit der Anweisung git merge
:
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
Ihnen wird bei diesem Zusammenführen der Ausdruck „fast-forward“ auffallen.
Da der Commit C4
, auf den der von Ihnen eingebundene Branch hotfix
zeigt, direkt vor dem Commit C2
liegt, auf dem Sie sich befinden, bewegt Git den Pointer einfach nach vorne.
Um es anders auszudrücken, wenn Sie versuchen, einen Commit mit einem Commit zusammenzuführen, der durch Verfolgen der Historie des ersten Commits erreicht werden kann, vereinfacht Git die Dinge, indem er den Zeiger nach vorne bewegt, da es keine abweichenden Arbeiten gibt, die miteinander gemergt werden müssen – das wird als „fast-forward“ bezeichnet.
Ihre Änderung befindet sich nun im Schnappschuss des Commits, auf den der master
-Branch zeigt und Sie können Ihre Fehlerbehebung anwenden.

master
wurde zu hotfix
„fast-forwarded“Nachdem Ihre überaus wichtige Fehlerbehebung bereitgestellt wurde, können Sie sich wieder dem zuwenden, woran Sie gerade gearbeitet haben, als Sie unterbrochen wurden.
Zunächst sollten Sie jedoch den hotfix
-Branch löschen, weil Sie diesen nicht länger benötigen – schließlich verweist der master
-Branch auf den selben Entwicklungsstand.
Sie können ihn mit der Anweisung git branch
und der Option -d
löschen:
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
Jetzt können Sie zu dem Branch zurückwechseln, auf dem Sie mit Ihren Arbeiten an „Issue #53“ begonnen hatten, und daran weiter arbeiten.
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)

iss53
weitergeführtEs ist erwähnenswert, dass die Arbeit, die Sie in Ihrem hotfix
-Branch durchgeführt haben, nicht in den Dateien in Ihrem iss53
-Branch enthalten ist.
Wenn Sie diese Änderungen übernehmen müssen, können Sie in Ihren master
-Branch den iss53
-Zweig einbinden indem Sie git merge master
ausführen, oder Sie können warten, bis Sie sich später entscheiden, den iss53
-Zweig wieder zurück nach master
zu pullen.
Einfaches Merging
Angenommen, Sie haben entschieden, dass Ihr Issue #53 abgeschlossen ist und Sie bereit sind, ihn in Ihren „Master“ Branch zu integrieren.
Dann werden Sie Ihren iss53
-Branch in den master
-Branch mergen, so wie Sie es zuvor mit dem hotfix
-Branch gemacht haben.
Sie müssen nur mit der Anweisung checkout
zum dem Branch zu wechseln, in welchen Sie etwas einfließen lassen wollen und dann die Anweisung git merge
ausführen:
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
Das sieht ein bisschen anders aus, als das Merging mit dem hotfix
-Branch, das Sie zuvor gemacht haben.
Hier hat sich der Entwicklungsverlauf an einem früheren Zustand geteilt.
Da der Commit auf dem Branch, auf dem Sie sich gerade befinden, kein unmittelbarer Vorgänger der Branch ist, in den Sie fusionieren, muss Git einige Arbeiten erledigen.
In diesem Fall führt Git einen einfachen Drei-Wege-Merge durch, indem er die beiden Schnappschüsse verwendet, auf die die Branch-Spitzen und der gemeinsame Vorfahr der beiden zeigen.

merge
benutzt werdenAnstatt einfach den Zeiger des Branches vorwärts zu bewegen, erstellt Git einen neuen Schnappschuss, der aus dem Drei-Wege-Merge resultiert und erzeugt automatisch einen neuen Commit, der darauf zeigt. Das wird auch als Merge-Commit bezeichnet und ist ein Spezialfall, weil er mehr als nur einen Vorgänger hat.

Da Ihre Änderungen jetzt eingeflossen sind, haben Sie keinen weiteren Bedarf mehr für den iss53
-Branch.
Sie können das Ticket in Ihrem Ticket-Tracking-System schließen und den Branch löschen:
$ git branch -d iss53
Einfache Merge-Konflikte
Gelegentlich verläuft der Merge-Prozess nicht ganz reibungslos.
Wenn Sie in den beiden Branches, die Sie zusammenführen wollen, an der selben Stelle in der selben Datei unterschiedliche Änderungen vorgenommen haben, wird Git nicht in der Lage sein, diese sauber zusammenzuführen.
Wenn Ihr Fix für „Issue #53“ den gleichen Teil einer Datei wie der Branch hotfix
geändert hat, erhalten Sie einen Merge-Konflikt, der ungefähr so aussieht:
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
Git konnte automatisch keinen neuen Merge-Commit erstellen.
Es hat den Prozess angehalten, bis Sie den Konflikt beseitigt haben.
Wenn Sie sehen möchten, welche Dateien nach einem Merge-Konflikt an einem bestimmten Punkt nicht zusammengeführt wurden, können Sie git status
ausführen:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
Alles, was Merge-Konflikte ausgelöst hat und nicht behoben wurde, wird als unmerged
angezeigt.
Git fügt den Dateien, die Konflikte haben, Standardmarkierungen zur Konfliktlösung hinzu, so dass Sie sie manuell öffnen und diese Konflikte lösen können.
Ihre Datei enthält einen Bereich, der in etwa so aussieht:
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
Das bedeutet, die Version in HEAD
(Ihres master
-Branches, denn der wurde per checkout
aktiviert, als Sie das merge
gestartet haben) ist der obere Teil des Blocks (alles oberhalb von =======
), und die Version aus dem iss53
-Branch sieht wie der darunter befindliche Teil aus.
Um den Konflikt zu lösen, müssen Sie sich entweder für einen der beiden Teile entscheiden oder Sie führen die Inhalte selbst zusammen.
Sie können diesen Konflikt beispielsweise lösen, indem Sie den gesamten Block durch diesen ersetzen:
<div id="footer">
please contact us at email.support@github.com
</div>
Diese Lösung hat von beiden Teilen etwas und die Zeilen mit <<<<<<<
, =======
, und >>>>>>>
wurden vollständig entfernt.
Nachdem Sie alle problematischen Bereiche in allen von dem Konflikt betroffenen Dateien beseitigt haben, führen Sie einfach die Anweisung git add
für alle betroffenen Dateien aus, um sie als gelöst zu markieren.
Dieses Staging der Dateien markiert sie für Git als bereinigt.
Wenn Sie ein grafisches Tool benutzen möchten, um die Probleme zu lösen, dann können Sie git mergetool
verwenden, welches ein passendes grafisches Merge-Tool startet und Sie durch die Konfliktbereiche führt:
$ git mergetool
This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html
Normal merge conflict for 'index.html':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (opendiff):
Wenn Sie ein anderes Merge-Tool anstelle des Standardwerkzeugs verwenden möchten (Git wählte in diesem Fall opendiff
, da die Anweisung auf einem Mac ausgeführt wurde), dann können Sie alle unterstützten Werkzeuge oben – nach „one of the following tools“ – aufgelistet sehen.
Tippen Sie einfach den Namen des gewünschten Programms ein.
Note
|
Wenn Sie fortgeschrittenere Werkzeuge zur Lösung kniffliger Merge-Konflikte benötigen, erfahren Sie mehr daüber in Kapitel 7 Fortgeschrittenes Merging. |
Nachdem Sie das Merge-Tool beendet haben, werden Sie von Git gefragt, ob das Zusammenführen erfolgreich war.
Wenn Sie dem Skript bestätigen, dass es das war, wird die Datei der Staging Area hinzugefügt und der Konflikt als gelöst zu markiert.
Sie können den Befehl git status
erneut ausführen, um zu überprüfen, ob alle Konflikte gelöst wurden:
$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: index.html
Wenn Sie damit zufrieden sind und Sie geprüft haben, dass alles, was Konflikte aufwies, zum Index hinzugefügt wurde, können Sie die Anweisung git commit
ausführen, um den Merge-Commit abzuschließen.
Die standardmäßige Commit-Nachricht sieht ungefähr so aus:
Merge branch 'iss53'
Conflicts:
index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: index.html
#
Sie können dieser Commit-Nachricht noch Details darüber hinzufügen, wie Sie diesen Merge-Konflikt gelöst haben. Es könnte für künftige Betrachter dieses Commits hilfreich sein zu verstehen, warum Sie was getan haben, falls es nicht offensichtlich ist.