1. Was sind Branches und wozu braucht man sie?
Die Arbeit mit branches in Git ist einer der Schlüsselaspekte der Versionsverwaltung. Sie erlaubt es, mehrere Entwicklungslinien parallel in einem Repository voranzutreiben. Branching macht Git zu einem mächtigen Werkzeug für Zusammenarbeit, Experimente und die Verwaltung verschiedener Versionen eines Projekts.
gitGraph
commit id: "Initial setup"
commit id: "Add base features"
branch feature/new-idea
checkout feature/new-idea
commit id: "Implement new logic"
commit id: "Refactor the logic"
checkout main
commit id: "Urgent bugfix on main"
merge feature/new-idea
commit id: "Prepare for release"
main zweigt eine neue Branch,
feature/new-idea, für die sichere Entwicklung ab. Nach Abschluss der Arbeit wird sie wieder in
main zusammengeführt.
Stellen Sie sich vor, Sie möchten in Ihrem Projekt etwas grundlegend überarbeiten oder ein riskantes Experiment durchführen. Wie würden Sie ohne Git vorgehen? Wahrscheinlich würden Sie das ganze Projekt in einen neuen Ordner kopieren und dort arbeiten. Gefällt Ihnen das Ergebnis – würden Sie es in den Hauptordner übernehmen. Wenn nicht – löschen Sie die Kopie einfach.
Branches in Git funktionieren nach demselben Prinzip, nur wesentlich eleganter. Betrachten wir das am Beispiel des Schreibens eines Buches:
- Sie haben ein fertiges Manuskript (das ist Ihre Hauptbranch
main). - Sie möchten ein alternatives Ende schreiben (Sie erstellen eine neue Branch, z. B.
feature/new-idea). - Sie schreiben das neue Ende, ohne den Haupttext des Manuskripts zu berühren (Sie arbeiten in der neuen Branch).
- Wenn sich das neue Ende als besser erweist, ersetzen Sie damit das alte (Sie führen die Branches zusammen –
merge). - Den alten Entwurf mit dem nicht benötigten Ende können Sie löschen (Sie löschen die Branch).
2. Erstellen eines neuen Branches und Arbeiten darin
Schritt 1. Öffnen Sie das Branch-Management-Menü.
In der oberen Leiste der IDE befindet sich ein Widget, das den Namen des aktuellen Branches anzeigt (standardmäßig – main). Klicken Sie darauf und wählen Sie + New Branch.
Schritt 2. Name des neuen Branches.
Gute Praxis ist es, Branches entsprechend der Aufgabe zu benennen, die Sie lösen. Zum Beispiel feature/add-usage-examples.
Nach dem Erstellen des Branches wechselt die IDE automatisch auf ihn. Sie sehen den neuen Namen im selben Widget.
Schritt 3. Änderungen vornehmen und committen.
Jetzt befinden Sie sich in Ihrer „Sandbox“. Fügen wir in unsere Datei README.md einen neuen Abschnitt mit Anwendungsbeispielen ein. Nehmen Sie die Änderungen vor und führen Sie einen commit durch, wie Sie es in der vorherigen Vorlesung gelernt haben.
3. Zwischen Branches wechseln
Ihre Änderungen mit Anwendungsbeispielen sind nun sicher im Branch feature/add-usage-examples gespeichert. Kehren wir zur Hauptbranch main zurück und schauen, was dort ist.
Schritt 1. Klicken Sie erneut auf das Widget mit dem Namen des aktuellen Branches.
Schritt 2. Wählen Sie in der Liste Local oder Recent den Branch main aus und klicken Sie im eingeblendeten Untermenü auf Checkout.
Schritt 3. Ergebnis prüfen.
Sobald Sie gewechselt haben, öffnen Sie die Datei README.md. Sie werden sehen, dass der Abschnitt mit den Anwendungsbeispielen hier nicht vorhanden ist! Er blieb im anderen Branch. So können Sie an neuer Funktionalität arbeiten, ohne die stabile Version im Branch main anzutasten.
4. Branches zusammenführen (Merge)
Der Befehl merge nimmt alle Commits aus dem Branch feature/add-examples (in diesem Fall Commit C3) und vereinigt sie mit dem aktuellen Branch main, wobei ein neuer Merge-Commit erstellt wird.
gitGraph
commit id: "C1"
commit id: "C2"
branch feature/add-examples
checkout feature/add-examples
commit id: "C3: Add new section"
checkout main
merge feature/add-examples
Sie haben also Ihre Aufgabe im Branch feature/add-usage-examples abgeschlossen und möchten diese Änderungen in das Hauptprojekt übernehmen.
Schritt 1. Wechseln Sie auf den Ziel-Branch.
Stellen Sie sicher, dass Sie sich in dem Branch befinden, WOHIN Sie die Änderungen übernehmen möchten. In unserem Fall ist das main.
Schritt 2. Führen Sie den Merge durch.
Klicken Sie erneut auf das Branch-Management-Widget. Wählen Sie in der Liste den Branch aus, VON WO Sie die Änderungen übernehmen möchten (feature/add-usage-examples), und wählen Sie im Untermenü Merge feature/add-usage-examples in main.
Schritt 3. Ergebnis prüfen.
Jetzt ist in der Datei README.md im Branch main Ihr neuer Abschnitt mit Beispielen erschienen. Sie haben Ihre Arbeit erfolgreich mit der Hauptversion des Projekts zusammengeführt!
5. Konflikte beim Zusammenführen: Keine Angst, das ist normal!
Manchmal entstehen beim Zusammenführen von Branches Konflikte. Das passiert, wenn in beiden Branches dieselben Zeilen in derselben Datei geändert wurden. Git kann nicht selbst entscheiden, welche Version richtig ist, und bittet um Ihre Hilfe.
gitGraph
commit id: "C1: Gemeinsame Basis"
branch feature/new-title
checkout main
commit id: "C2: Änderung in main"
checkout feature/new-title
commit id: "C3: Änderung in feature"
main und
feature/new-title, haben neue Commits (C2 und C3), die auf einem gemeinsamen Vorfahren (C1) basieren. Das führt garantiert zu einem Konflikt beim Merge.
Lassen Sie uns einen Konflikt simulieren:
- Stellen Sie sicher, dass Sie sich im Branch
mainbefinden und keine ungesicherten Änderungen haben. - Erstellen Sie sofort einen neuen Branch
feature/new-title, wechseln Sie jedoch noch nicht darauf. Vergewissern Sie sich, dass das Häkchen bei Checkout branch entfernt ist. - Ändern Sie nun, während Sie sich im Branch
mainbefinden, die erste Zeile inREADME.mdauf „My Awesome Project“ und führen Sie einencommitdurch. - Wechseln Sie in den Branch
feature/new-title. Sie werden sehen, dass die erste Zeile inREADME.mdhier noch die alte ist: das ist der Zustand der Datei zum Zeitpunkt der Branch-Erstellung. Ändern Sie dieselbe Zeile auf „My Super Project“ und führen Sie einencommitdurch. - Kehren Sie zum Branch
mainzurück und führen Sie den Merge mitfeature/new-titleaus.
Nun erkennt Git, dass beide Branches neue, voneinander abweichende Historien seit ihrem gemeinsamen Vorfahren haben. In beiden Historien wurde dieselbe Zeile geändert, daher kann Git nicht auswählen, welche Version korrekt ist, und zeigt Ihnen ein Fenster zur Konfliktauflösung.
Merge Revision
Was Sie hier sehen:
- Links (Your changes): die Dateiversion aus Ihrem aktuellen Branch (
main). - Rechts (Changes from branch...): die Dateiversion aus dem Branch, den Sie mergen.
- In der Mitte (Result): die endgültige Dateiversion, die Sie zusammenstellen sollen.
Sie können auf die Pfeile >> oder << klicken, um jeweils die eine oder andere Variante vollständig zu übernehmen.
Wenn Sie mit dem Ergebnis im mittleren Bereich zufrieden sind, klicken Sie auf Apply. Die IDE erstellt automatisch einen Merge-Commit, und der Konflikt ist gelöst.
Warum ist kein Konflikt aufgetreten?
Es kann vorkommen, dass Sie alle Schritte ausgeführt haben, aber kein Konflikt auftritt. Meist liegt das daran, dass Git einen fast-forward merge durchführen konnte, weil die Historie eines Branches die der anderen einfach fortsetzt. Damit ein Konflikt garantiert ist, müssen die Historien der Branches von einem gemeinsamen Vorfahren aus in unterschiedliche Richtungen auseinanderlaufen.
Beispiel:
- Sie haben einen Commit in
main(nehmen wir an, C1). - Sie machen einen neuen Commit in
mainmit dem Text „My Awesome Project“. Der Branchmainzeigt nun auf Commit C2 (main -> C1 -> C2). - Sie erstellen den Branch
feature/new-titlevom aktuellen Stand des Branches main. Das bedeutet, der neue Branch beginnt ebenfalls bei Commit C2. - Sie machen einen Commit in
feature/new-titlemit dem Text „My Super Project“. Dieser Branch „geht voran“ und zeigt jetzt auf Commit C3 (feature/new-title -> C1 -> C2 -> C3). - Sie kehren zu
mainzurück (der sich noch auf Commit C2 befindet) und geben den Befehl, feature/new-title zu mergen.
Git schaut sich die Situation an und sieht, dass der Branch main ein direkter Vorfahre des Branches feature/new-title ist. In der Historie von main gab es keine neuen Commits, während Sie im anderen Branch gearbeitet haben. Git denkt: „Ah, hier muss man nur main bis zum Commit C3 vorspulen. Es gibt keine Widersprüche.“ Und es verschiebt einfach den Zeiger von main auf Commit C3.
gitGraph
commit id: "C1"
commit id: "C2"
branch feature/new-title
checkout feature/new-title
commit id: "C3"
checkout main
merge feature/new-title
6. Änderungshistorie ansehen
Um besser zu verstehen, was in Ihrem Projekt passiert, ist es hilfreich, einen Blick auf seine Historie zu werfen.
Öffnen Sie den Tab Git im unteren Bereich der IDE und wählen Sie Log. Sie sehen eine grafische Darstellung all Ihrer Branches und Commits. Das hilft, nachvollziehbar zu sehen, welcher Branch von welchem abgezweigt ist und wo sie zusammengeführt wurden.
Hier können Sie auf jeden Commit klicken, um zu sehen, welche Änderungen er enthält und wer ihn wann erstellt hat. Das ist eine echte Zeitmaschine für Code!
GO TO FULL VERSION