02 Code-Qualität in der Praxis: Feature Branch Entwicklung - Von Cowboy Coding zu professionellen Workflows
October 2025 (9050 Words, 51 Minutes)
1. Einführung: Das Problem mit Push zu Main
Sie haben in Kapitel 02 (Code-Qualität in der Praxis) über Code-Qualitätswerkzeuge gelernt—Ruff für Linting und Formatierung, Pyright für Type Checking. Sie wissen wie man überprüft, ob Ihr Code professionellen Standards entspricht.
Aber hier ist, was typischerweise in Studentenprojekten passiert:
# Schreibe etwas Code
$ git add .
$ git commit -m "Added new feature"
$ git push origin main
# Hoffe auf das Beste 🤞
Dieser Workflow hat ernsthafte Probleme:
- Keine Überprüfung vor dem Deployment - Ihr Code geht direkt in die Produktion (den
mainBranch) - Keine Chance, Probleme zu erkennen - Einmal gepusht, ist er live
- Breaking Changes betreffen alle - Wenn Ihr Code Bugs hat, ist das gesamte Team blockiert
- Keine Zusammenarbeit - Andere Entwickler können Ihre Änderungen nicht überprüfen oder Verbesserungen vorschlagen
- Schwierig nachzuvollziehen, was sich geändert hat - Alle Commits vermischt auf
main
Konsequenz in der Praxis:
Stellen Sie sich vor, Sie arbeiten an einem Teamprojekt. Sie pushen kaputten Code zu main um 23 Uhr. Ihr Teamkollege pullt am nächsten Morgen den neuesten Code, um seinen Tag zu beginnen. Seine gesamte Entwicklungsumgebung ist jetzt kaputt. Er verbringt 2 Stunden mit Debugging, bevor er merkt, dass das Problem in Ihrem Code von letzter Nacht liegt. Deshalb pushen professionelle Teams nicht direkt zu main.
2. Lernziele
Am Ende dieser Vorlesung werden Sie:
- Gits fundamentale Konzepte verstehen: Working Directory, Staging Area, Commits und Branches
- Feature Branch Workflows beherrschen: Erstellen, Arbeiten an und Mergen von Feature Branches
- Pull Request Workflows lernen: Wie man Code Review vor dem Mergen anfordert
- Branch Protection verstehen: Direktes Pushen zu
mainverhindern - Für CI/CD vorbereiten: Das Fundament für automatisierte Qualitätsprüfungen legen (Kapitel 02 (Automatisierung und CI/CD))
- Professionelle Kollaborationsmuster anwenden: Wie echte Softwareteams arbeiten
3. Teil 1: Git Grundlagen - Verstehen, was Sie getan haben
Sie haben Git benutzt, aber verstehen Sie, was wirklich passiert? Lassen Sie uns die Kernkonzepte entmystifizieren.
3.1 Die drei Zustände von Git
Git hat drei Hauptzustände, in denen sich Ihre Dateien befinden können:
1. Working Directory (Modifiziert)
- Dateien, die Sie aktiv bearbeiten
- Änderungen noch nicht in Git gespeichert
- Status: “Ich habe diese Datei geändert, aber Git noch nicht informiert”
2. Staging Area (Staged)
- Änderungen, die für den nächsten Commit markiert sind
- Eine Vorschau Ihres nächsten Commits
- Status: “Ich möchte diese Änderungen in meinem nächsten Commit haben”
3. Repository (Committed)
- Änderungen permanent in Gits History gespeichert
- Snapshot Ihres Projekts zu einem bestimmten Zeitpunkt
- Status: “Dies ist Teil der History meines Projekts”
Der Git Workflow:
Working Directory → Staging Area → Repository
(Modifiziert) (Staged) (Committed)
↓ ↓ ↓
edit file git add file git commit -m "..."
3.2 Visualisierung von Gits drei Zuständen
Beispiel-Szenario: Lassen Sie uns einige Code-Qualitätsprobleme in der main.py unseres Road Profile Viewers beheben:
# 1. WORKING DIRECTORY (Modifiziert)
# Sie bearbeiten main.py, um das Import-Statement zu korrigieren
$ vim main.py # Ändere: import sys,os → import sys\nimport os
$ git status
Changes not staged for commit:
modified: main.py
# 2. STAGING AREA (Staged)
$ git add main.py
$ git status
Changes to be committed:
modified: main.py
# 3. REPOSITORY (Committed)
$ git commit -m "Fix PEP8 violation: separate imports onto different lines"
$ git status
nothing to commit, working tree clean
Was ist gerade passiert:
1. Working Directory (Modifiziert)
┌─────────────────────────────────┐
│ main.py (bearbeitet) │
│ Korrigiert: import sys,os │
│ → import sys │
│ → import os │
└─────────────────────────────────┘
↓ git add
2. Staging Area (Staged)
┌─────────────────────────────────┐
│ main.py │
│ Bereit für Commit │
└─────────────────────────────────┘
↓ git commit
3. Repository (Committed)
┌─────────────────────────────────┐
│ Commit: a1b2c3d │
│ "Fix PEP8 violation: separate │
│ imports onto different lines" │
│ Timestamp: 2025-10-16 │
└─────────────────────────────────┘
3.3 Warum die Staging Area existiert
Frage: Warum nicht direkt vom Working Directory committen?
Antwort: Die Staging Area gibt Ihnen Kontrolle darüber, was in jeden Commit geht.
Beispiel - Trennung von Belangen:
# Sie haben mehrere Probleme in main.py behoben:
$ git status
Changes not staged for commit:
modified: main.py # Mehrere PEP8-Verstöße behoben
# Statt EINEM großen Commit, erstelle logische Commits:
# Zuerst: Import-Probleme beheben
$ git add -p main.py # Wähle nur import-bezogene Änderungen
$ git commit -m "Fix PEP8: Separate imports and remove unused imports"
# Zweitens: Spacing-Probleme beheben
$ git add -p main.py # Wähle nur Spacing-Änderungen
$ git commit -m "Fix PEP8: Add proper spacing around operators"
# Drittens: Namenskonvention beheben
$ git add main.py # Füge verbleibende Änderungen hinzu
$ git commit -m "Fix PEP8: Rename HelperFunction to helper_function"
Vorteile:
- ✅ Jeder Commit hat einen einzelnen, klaren Zweck (Imports, Spacing, Benennung)
- ✅ Einfacher, die History später zu verstehen (“welcher Commit hat Imports kaputt gemacht?”)
- ✅ Einfacher, spezifische Änderungen rückgängig zu machen (nur die Namensänderung rückgängig machen, wenn nötig)
- ✅ Besser für Code Review (Reviewer sieht logische Progression)
3.4 Git Status - Ihr bester Freund
Der git status Befehl zeigt Ihnen genau, in welchem Zustand sich Ihre Dateien befinden:
$ git status
On branch feature/fix-code-quality
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: main.py ← STAGED (Import-Fixes)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: main.py ← MODIFIED (Spacing-Fixes nicht staged)
Untracked files:
(use "git add <file>..." to include in what will be committed)
temp_notes.txt ← UNTRACKED (Git kennt diese nicht)
Interpretation:
- Staged Dateien (
main.py- Import-Änderungen): Werden im nächsten Commit enthalten sein - Modified Dateien (
main.py- Spacing-Änderungen): Geändert, aber nicht staged (werden nicht im nächsten Commit sein) - Untracked Dateien (
.ruff_cache/): Neues Verzeichnis, das Git nicht verfolgt (zu.gitignorehinzufügen)
Pro-Tipp: Führen Sie git status ständig aus. Es ist Ihre Karte, die zeigt, wo Sie sind und was passieren wird.
3.5 Commits verstehen
Ein Commit ist ein Snapshot Ihres Projekts zu einem bestimmten Zeitpunkt.
Was ist in einem Commit?
Commit: a1b2c3d4
Author: Student Name <student@example.com>
Date: 2025-10-16 10:30:00 +0200
Fix PEP8 violations: imports and spacing
- Separate multiple imports onto different lines
- Remove unused sys and os imports
- Add proper spacing around operators in generate_road_profile
- Add spaces after commas in function parameters
Changed files:
main.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
Schlüsselkomponenten:
- Commit Hash (
a1b2c3d4...): Eindeutige Kennung für diesen Commit - Author & Datum: Wer die Änderung gemacht hat und wann
- Commit Message: Beschreibung was sich geändert hat und warum
- Diff: Tatsächliche Code-Änderungen (4 Zeilen hinzugefügt, 4 Zeilen entfernt)
Commits sind permanent - Einmal committed, existiert dieser Snapshot für immer in Gits History (es sei denn, Sie löschen ihn mit Gewalt).
3.6 Git History anzeigen
Commit History anzeigen:
$ git log --oneline --graph --all
* d4e5f6g (HEAD -> feature/fix-code-quality) Fix PEP8: Rename helper_function
* a1b2c3d Fix PEP8: Add proper spacing around operators
* 7h8i9j0 Fix PEP8: Separate imports and remove unused ones
* k1l2m3n (origin/main, main) Add Road Profile Viewer application
* f9e8d7c Initial commit
Aufschlüsselung:
*= Commit in der HistoryHEAD ->= Wo Sie sich gerade befinden (auf Feature-Branch, Code-Qualität korrigieren)(origin/main, main)= Branch-Zeiger (main Branch)d4e5f6g= Commit Hash (gekürzt)Fix PEP8...= Commit Message (beschreibt die Qualitätskorrektur)
3.7 Häufige Git Status Szenarien
Szenario 1: Sauberer Working Tree
$ git status
On branch main
nothing to commit, working tree clean
✅ Alle Änderungen sind committed. Sicher, Branches zu wechseln.
Szenario 2: Nicht committete Änderungen
$ git status
On branch main
Changes not staged for commit:
modified: main.py
⚠️ Sie haben ungespeicherte Änderungen. Committen Sie sie oder stashen Sie sie, bevor Sie Branches wechseln.
Szenario 3: Staged aber nicht committed
$ git status
On branch main
Changes to be committed:
modified: main.py
⚠️ Änderungen sind staged, aber noch nicht in der History gespeichert. Committen Sie sie!
Szenario 4: Sowohl staged als auch unstaged
$ git status
On branch feature/fix-code-quality
Changes to be committed:
modified: main.py ← Staged (Import-Korrekturen)
Changes not staged for commit:
modified: main.py ← Nicht staged (gerade gemachte Spacing-Korrekturen)
⚠️ Sie haben die Import-Korrekturen in main.py staged, dann nochmal bearbeitet, um Spacing zu korrigieren. Der nächste Commit wird nur die Import-Korrekturen enthalten, außer Sie machen git add nochmal.
4. Teil 2: Branches - Isoliert arbeiten
4.1 Was ist ein Branch?
Ein Branch ist eine unabhängige Entwicklungslinie. Denken Sie daran wie an ein Paralleluniversum, in dem Sie Änderungen machen können, ohne die Hauptzeitlinie zu beeinflussen.
Analogie: Ein Buch schreiben
main branch: Kapitel 1 → Kapitel 2 → Kapitel 3 → Veröffentlichtes Buch
↓
feature branch: Kapitel 2 → Experimentiere mit alternativem Ende
→ Schreibe Kapitel komplett neu
→ Vorschau mit Testlesern
→ Entscheide, ob es besser ist
↓
Merge zurück → Verwende neue Version im finalen Buch
4.2 Die technische Realität: Branches sind Zeiger
Wichtiges Missverständnis: Viele Studenten denken, ein Branch ist ein Commit. Das ist falsch.
Die Wahrheit: Ein Branch ist nur ein leichtgewichtiger, beweglicher Zeiger auf einen Commit.
Was tatsächlich in Git existiert:
-
Commits: Die tatsächlichen Snapshots Ihres Codes. Sie bilden eine Kette (History) und ändern sich nie, sobald sie erstellt wurden. Jeder Commit hat einen eindeutigen Hash (wie
1ff0a77). -
Branches: Nur Labels, die auf Commits zeigen. Sie sind bewegliche Referenzen, keine Commits selbst.
-
Tags: Auch Zeiger auf Commits, aber sie bewegen sich nicht (sie sind permanente Marker).
Visuelle Darstellung:
Alle drei Zeiger (main, feature/fix-code-quality, v1.0) referenzieren denselben Commit 1ff0a77. Sie sind keine Kopien des Commits—sie sind nur Labels, die darauf zeigen.
Was passiert, wenn Sie einen Branch erstellen:
$ git checkout -b feature/new-feature
Git kopiert keine Commits. Es erstellt nur einen neuen Zeiger namens feature/new-feature, der auf denselben Commit zeigt, auf dem Sie waren.
Was passiert, wenn Sie auf einem Branch commiten:
$ git commit -m "Add new feature"
Git:
- Erstellt einen neuen Commit (z.B.
2aa3b44) - Bewegt den aktuellen Branch-Zeiger, um auf diesen neuen Commit zu zeigen
- Lässt andere Branch-Zeiger unverändert
Vor dem Commit:
Nach dem Commit:
Was passiert, wenn Sie einen Branch umbenennen:
$ git branch -m feauture/fix feature/fix
Git ändert keine Commits. Es:
- Erstellt einen neuen Zeiger namens
feature/fix, der auf denselben Commit zeigt - Löscht den alten Zeiger namens
feauture/fix
Die Commits selbst sind unverändert, weshalb Tags und andere Referenzen perfekt weiter funktionieren!
Was ist mit HEAD?
Sie haben wahrscheinlich HEAD in der Git-Ausgabe gesehen und sich gefragt, was das bedeutet. HEAD ist ein weiterer Zeiger—ein spezieller, der Git sagt, wo Sie sich gerade befinden.
Die einfache Erklärung:
HEAD ist wie ein “Sie sind hier”-Marker auf einer Karte. Er zeigt auf Ihre aktuelle Position in der Git-History.
Wie HEAD funktioniert:
Meistens zeigt HEAD auf einen Branch-Zeiger, der auf einen Commit zeigt. Dies nennt man “attached HEAD” Zustand.
In diesem Diagramm:
1ff0a77ist ein Commit (der tatsächliche Code-Snapshot)mainist ein Branch-Zeiger (zeigt auf den Commit)HEADzeigt aufmain(Sie sind gerade auf dem main Branch)
Wenn Sie Branches wechseln, bewegt sich HEAD:
$ git checkout feature/fix-code-quality
Vor dem Wechsel:
Nach dem Wechsel:
HEAD zeigt jetzt auf den Feature-Branch statt auf main. Das ist alles, was git checkout oder git switch macht—es bewegt den HEAD-Zeiger.
Wenn Sie committen:
$ git commit -m "Add validation"
Vor dem Commit:
Nach dem Commit:
Git erstellt den neuen Commit 2aa3b44, bewegt den Branch-Zeiger (feature/fix-code-quality), um darauf zu zeigen, und HEAD folgt mit, weil er auf diesen Branch zeigt.
Sie haben HEAD schon gesehen!
Erinnern Sie sich an das hier von früher in der Vorlesung?
$ git log --oneline --graph --all
* d4e5f6g (HEAD -> feature/fix-code-quality) Fix PEP8: Rename helper_function
* a1b2c3d Fix PEP8: Add proper spacing around operators
(HEAD -> feature/fix-code-quality) bedeutet:
- Sie sind auf dem
feature/fix-code-qualityBranch - Dieser Branch zeigt auf Commit
d4e5f6g - Der Pfeil
->zeigt, dass HEAD auf den Branch zeigt
Detached HEAD (kurze Erwähnung):
Manchmal sehen Sie eine Warnung über “detached HEAD state”. Das passiert, wenn HEAD direkt auf einen Commit zeigt, statt auf einen Branch:
$ git checkout 1ff0a77 # Einen spezifischen Commit per Hash auschecken
Detached HEAD:
HEAD → 1ff0a77 (kein Branch-Zeiger dazwischen)
Git warnt Sie, weil alle Commits, die Sie machen, zu keinem Branch gehören und verloren gehen könnten. Sie werden das in der normalen Arbeit selten brauchen, aber jetzt wissen Sie, was es bedeutet, wenn Sie es sehen!
Kernaussage:
- HEAD = “Sie sind hier”-Zeiger
- Normalerweise: HEAD → Branch → Commit (attached HEAD)
- Selten: HEAD → Commit (detached HEAD, Git wird Sie warnen)
git checkout/git switch= HEAD zu einem anderen Branch bewegen- Wenn Sie committen, bewegt sich der Branch, auf den HEAD zeigt, vorwärts
Warum das wichtig ist:
- Branches sind günstig: Einen Branch zu erstellen bedeutet nur, einen Zeiger zu erstellen (ein paar Bytes)
- Branches sind schnell: Kein Kopieren von Dateien oder Commits nötig
- Mehrere Branches können auf denselben Commit zeigen: Das ist völlig normal
- Einen Branch zu löschen, löscht keine Commits: Es entfernt nur den Zeiger
- HEAD zeigt Ihnen, wo Sie sind: HEAD zu verstehen hilft Ihnen zu verstehen, was Git-Befehle tatsächlich tun
Beispiel aus der Praxis:
$ git log --oneline --all --graph
* 1ff0a77 (HEAD -> main, tag: lecture-04, origin/main, feature/fix-code-quality) Add Road Profile Viewer
* e341990 Fix imports
* 032f36c Initial commit
Hier können Sie sehen:
- Commit
1ff0a77existiert (der tatsächliche Code-Snapshot) - Vier Zeiger referenzieren ihn alle:
HEAD,main,tag: lecture-04,origin/main, undfeature/fix-code-quality - Keiner dieser Zeiger IST der Commit—sie ZEIGEN nur DARAUF
📝 Übungszeit: Testen Sie Ihr Verständnis!
Jetzt, da Sie gelernt haben, wie Git-Branches als Zeiger funktionieren, ist der perfekte Zeitpunkt, Ihr Verständnis durch Übung zu festigen.
👉 Git-Zeiger-Übung: Branches und HEAD verstehen
Diese Übung enthält 15 sorgfältig konzipierte Fragen, die Ihnen helfen:
- Zu visualisieren, wie sich Zeiger während Git-Operationen bewegen
- Den Unterschied zwischen Branches, Commits und HEAD zu verstehen
- Merge-Typen zu identifizieren (Fast-Forward vs. Three-Way)
- Gängige Git-Workflows durch visuelle Diagramme zu meistern
Jede Frage zeigt Ihnen Git-Graphen mit Commit-Hashes, Branches und Zeigern. Sie müssen vorhersagen, was nach verschiedenen Git-Befehlen passiert—genau die Art von Denken, die Sie sicher im Umgang mit Git macht!
Warum jetzt üben?
- Die Konzepte sind frisch in Ihrem Kopf
- Sie wenden sofort an, was Sie gerade gelernt haben
- Die Übung festigt die Zeiger-Mechanik, bevor wir weitergehen
- Es ist einfacher, inkrementell zu lernen als später alles auf einmal
Nehmen Sie sich 15-20 Minuten Zeit, um die Übung durchzuarbeiten. Machen Sie sich keine Sorgen, wenn Sie nicht alles beim ersten Versuch richtig haben—so lernen wir! Die Erklärungen helfen Ihnen, Missverständnisse zu klären.
4.3 Warum Branches verwenden?
Ohne Branches (Push zu main):
main: A → B → C → D (kaputt!) → E (fix D) → F (fix E) → G (funktioniert wieder)
↑
Alle sehen kaputten Code
Andere Entwickler blockiert
Schwierig zurückzusetzen
Mit Feature Branches:
main: A → B → C --------------------------------→ M (merge: getestetes Feature)
↘ ↗
feature branch: D → E (kaputt) → F (gefixt) → G (getestet)
↑
Nur Sie sehen das
Sicher zum Experimentieren
Einfach zu löschen, wenn schlecht
Vorteile:
- Isolation: Ihre Experimente beeinflussen andere nicht
- Sicherheit: Main Branch bleibt stabil und deploybar
- Experimentieren: Probieren Sie Ideen ohne Angst, Production zu brechen
- Review: Andere können Ihre Änderungen vor dem Mergen überprüfen
- Rollback: Einfach schlechte Ideen aufgeben, indem man den Branch löscht
4.4 Branch-Operationen
Alle Branches anzeigen:
$ git branch
main
* feature/fix-code-quality ← Sie sind hier (*)
feature/csv-export
Einen neuen Branch erstellen:
# Branch erstellen, aber auf aktuellem Branch bleiben
$ git branch feature/new-feature
# Branch erstellen UND zu ihm wechseln
$ git checkout -b feature/new-feature
# oder (moderne Syntax)
$ git switch -c feature/new-feature
Zwischen Branches wechseln:
$ git checkout feature/fix-code-quality
# oder (moderne Syntax)
$ git switch feature/fix-code-quality
Einen Branch löschen:
$ git branch -d feature/old-feature # Sicheres Löschen (nur wenn gemerged)
$ git branch -D feature/old-feature # Erzwungenes Löschen (auch wenn nicht gemerged)
4.5 Der Main Branch
Der main Branch (manchmal master in älteren Repositories genannt) ist besonders:
- Standard-Branch: Wird automatisch erstellt, wenn Sie ein Repository initialisieren
- Production Branch: Sollte immer stabil und deploybar sein
- Geschützt: In professionellen Teams können Sie nicht direkt zu
mainpushen - Merge-Ziel: Feature Branches werden in
maingemerged, wenn sie fertig sind
Goldene Regel: Pushen Sie niemals direkt zu main. Verwenden Sie immer Feature Branches.
4.6 Feature Branch Namenskonventionen
Gute Branch-Namen sind beschreibend und folgen einem Muster:
Gängige Muster:
feature/improve-road-curve # Neues Feature
fix/intersection-calculation # Bug Fix
refactor/ray-calculation # Code-Verbesserung
docs/add-usage-instructions # Dokumentations-Update
Schlechte Branch-Namen:
branch1 # Bedeutungslos
test # Zu vage
dominik-stuff # Nicht beschreibend
fix # Welcher Fix?
Best Practices:
- Verwenden Sie Kleinbuchstaben mit Bindestrichen (
kebab-case) - Beginnen Sie mit einem Präfix (
feature/,fix/,refactor/) - Seien Sie beschreibend, aber prägnant
- Referenzieren Sie Issue-Nummern, wenn zutreffend:
fix/42-intersection-bug
5. Teil 3: Feature Branch Workflow
5.1 Der vollständige Feature-Entwicklungs-Lebenszyklus
So arbeiten professionelle Entwickler mit Feature Branches:
1. Feature Branch von main erstellen
↓
2. Feature implementieren (mehrere Commits)
↓
3. Branch zu GitHub pushen
↓
4. Pull Request (PR) öffnen
↓
5. Automatisierte Checks laufen (wir richten das in Kapitel 02 (Automatisierung und CI/CD) ein!)
↓
6. Code Review durch Team
↓
7. Feedback adressieren (mehr Commits)
↓
8. Genehmigung + Checks bestanden
↓
9. Zu main mergen
↓
10. Feature Branch löschen
Lassen Sie uns das Schritt für Schritt durchgehen.
5.2 Schritt 1: Feature Branch erstellen
Beginne immer von einem aktuellen main Branch:
# 1. Zu main wechseln
$ git checkout main
# 2. Neueste Änderungen von GitHub pullen
$ git pull origin main
# 3. Feature Branch erstellen und zu ihm wechseln
$ git checkout -b feature/fix-code-qualityentication
Was das bewirkt:
- Stellt sicher, dass Ihr Branch vom neuesten Production-Code startet
- Erstellt eine isolierte Umgebung für Ihre Arbeit
- Verhindert Konflikte mit Änderungen anderer Entwickler
5.3 Schritt 2: Implementieren Sie Ihr Feature
Arbeiten Sie wie gewohnt, aber machen Sie kleine, logische Commits:
# Beginne mit der Behebung von Code-Qualitätsproblemen aus Kapitel 02
$ vim main.py # Behebe Import-Statement
# Prüfen Sie, was sich geändert hat
$ git status
$ git diff
# Stagen Sie Ihre Änderungen
$ git add main.py
# Committe mit beschreibender Message
$ git commit -m "Fix PEP8: Separate imports onto different lines"
# Arbeite weiter...
$ vim main.py # Behebe Spacing-Probleme
$ git add main.py
$ git commit -m "Fix PEP8: Add proper spacing around operators"
# Weitere Korrekturen...
$ vim main.py # Behebe Funktionsbenennung
$ git add main.py
$ git commit -m "Fix PEP8: Rename HelperFunction to helper_function"
# Prüfen Sie Ihre Commit History
$ git log --oneline
7h8i9j0 Fix PEP8: Rename HelperFunction to helper_function
d4e5f6g Fix PEP8: Add proper spacing around operators
a1b2c3d Fix PEP8: Separate imports onto different lines
Gute Commit-Praktiken:
✅ Machen Sie:
- Kleine, fokussierte Commits (eine Art Korrektur pro Commit: Imports, Spacing, Benennung)
- Schreiben Sie klare Commit Messages, die den Standard referenzieren (PEP8)
- Committen Sie oft (einfacher zurückzusetzen, wenn eine Korrektur etwas kaputt macht)
- Führen Sie Checks vor dem Committen aus:
uv run ruff check src/
❌ Machen Sie nicht:
- Riesige Commits mit allen 14 Korrekturen auf einmal
- Verwenden Sie vage Messages wie “Fixed stuff” oder “WIP” oder “more fixes”
- Committen Sie ohne zu testen (führen Sie Ruff zuerst aus!)
5.4 Schritt 3: Pushen Sie Ihren Branch zu GitHub
Beim ersten Push dieses Branches:
$ git push -u origin feature/fix-code-qualityentication
Was das bewirkt:
- Lädt Ihren lokalen Branch zu GitHub hoch
-u(oder--set-upstream) verknüpft Ihren lokalen Branch mit dem Remote-Branch- Nach dem ersten Push können Sie einfach
git pushverwenden
Nachfolgende Pushes (nach weiteren Commits):
$ git push
Prüfe auf GitHub:
- Gehen Sie zu Ihrem Repository auf GitHub
- Klicken Sie auf “Branches” oder “Code” Tab
- Sehen Sie Ihren neuen Branch aufgelistet
- GitHub zeigt möglicherweise ein Banner: “Compare & pull request”
5.5 Schritt 4: Einen Pull Request (PR) öffnen
Ein Pull Request (PR) ist eine Anfrage, Ihren Feature Branch in main zu mergen.
Auf GitHub:
- Klicken Sie auf “Pull requests” Tab
- Klicken Sie auf “New pull request”
- Base branch:
main(wohin Sie mergen MÖCHTEN) - Compare branch:
feature/fix-code-quality(Ihr Feature Branch) - Überprüfen Sie die Änderungen (Diff) - Sie sehen alle Ihre PEP8-Korrekturen hervorgehoben
- Klicken Sie auf “Create pull request”
- Füllen Sie aus:
- Title: Kurze Beschreibung (z.B., “Fix PEP8 violations in main.py”)
- Description: Was macht dieser PR? Warum? Besondere Hinweise?
- Klicken Sie auf “Create pull request”
Was in die PR-Beschreibung gehört:
## Beschreibung
Behebt alle PEP8-Verstöße, die von Ruff in `main.py` gefunden wurden (14 Fehler aus Kapitel 02 (Code-Qualität in der Praxis)).
## Änderungen
- **Import-Korrekturen**: Trenne mehrere Imports auf verschiedene Zeilen, entferne ungenutzte Imports
- **Spacing-Korrekturen**: Füge korrektes Spacing um Operatoren und nach Kommas hinzu
- **Benennungs-Korrekturen**: Benenne `HelperFunction` in `helper_function` um (snake_case)
- **Zeilenlängen-Korrekturen**: Breche lange Kommentare, um in 88 Zeichen-Limit zu passen
## Tests
- Alle Ruff Checks bestehen: `uv run ruff check src/`
- Code-Formatierung verifiziert: `uv run ruff format --check src/`
- Anwendung läuft noch korrekt: `uv run road-profile-viewer`
## Vorher/Nachher
- Vorher: 14 Ruff Fehler
- Nachher: 0 Ruff Fehler ✅
## Verwandte Issues
Adressiert Code-Qualitätsprobleme, die in Kapitel 02 (Code-Qualität in der Praxis) identifiziert wurden.
5.6 Schritt 5: Automatisierte Checks laufen
Hier kommt Kapitel 02 (Automatisierung und CI/CD) ins Spiel!
Wenn Sie einen PR öffnen, kann GitHub Actions automatisch:
- ✅ Code-Qualitätsprüfungen durchführen (Ruff)
- ✅ Type Checking durchführen (Pyright)
- ✅ Tests durchführen (pytest)
- ✅ Code Coverage prüfen
- ❌ Merge blockieren, wenn Checks fehlschlagen
Beispiel PR-Status:
✅ Ruff check passed (0 errors, war 14)
✅ Ruff format check passed
✅ Pyright type check passed
✅ Anwendung läuft erfolgreich
All checks passed - Ready to merge!
Oder wenn Sie vergessen haben, etwas zu beheben:
❌ Ruff check failed
- main.py:47:1: E501 Line too long (149 > 88 characters)
❌ Ruff format check failed
- main.py would be reformatted
Cannot merge until checks pass.
In diesem Fall müssten Sie:
# Behebe das verbleibende Problem lokal
$ vim main.py # Breche die lange Zeile
$ uv run ruff check src/ # Verifiziere, dass es behoben ist
$ git add main.py
$ git commit -m "Fix PEP8: Break long comment into multiple lines"
$ git push # Dies aktualisiert den PR automatisch!
Wir richten das in Kapitel 02 (Automatisierung und CI/CD) ein! Verstehe vorerst nur, dass PRs automatisierte Qualitätsgates haben können.
5.7 Schritt 6: Code Review
Code Review ist, wenn Teammitglieder Ihren Code lesen und Feedback geben.
Reviewer schauen nach:
- Korrektheit: Macht der Code, was er behauptet?
- Qualität: Ist er lesbar, wartbar, gut getestet?
- Design: Ist das der richtige Ansatz?
- Stil: Folgt er den Konventionen?
- Edge Cases: Was könnte schiefgehen?
Beispiel Review-Kommentar:
# Ihr Code nach Spacing-Korrekturen:
def generate_road_profile(num_points=100, x_max=80):
"""Generate a road profile..."""
x = np.linspace(0, x_max, num_points)
# Review-Kommentar: "Tolle Spacing-Korrekturen! Aber sollten wir hier
# Type Hints hinzufügen? Das würde Pyright glücklich machen und die
# Code-Dokumentation verbessern."
return x, y
Auf Feedback reagieren:
# Machen Sie angeforderte Änderungen
$ vim main.py # Füge Type Hints hinzu
# Committen Sie die Änderungen
$ git add main.py
$ git commit -m "Add type hints to generate_road_profile function"
# Pushe zum selben Branch (aktualisiert den PR automatisch!)
$ git push
Der PR aktualisiert sich automatisch mit Ihren neuen Commits! Kein neuer PR erforderlich.
5.8 Schritt 7: Feedback adressieren
Machen Sie weiter Änderungen, bis:
- ✅ Alle automatisierten Checks bestanden sind
- ✅ Alle Review-Kommentare adressiert sind
- ✅ Reviewer den PR genehmigt haben
Jedes Mal, wenn Sie pushen, aktualisiert sich der PR:
Commit History auf PR:
a1b2c3d Fix PEP8: Separate imports onto different lines
d4e5f6g Fix PEP8: Add proper spacing around operators
7h8i9j0 Fix PEP8: Rename HelperFunction to helper_function
k1l2m3n Add type hints to generate_road_profile ← Neuer Commit (aus Review)
m4n5o6p Fix PEP8: Break long comment into lines ← Noch ein neuer Commit
5.9 Schritt 8: Zu Main mergen
Sobald genehmigt und alle Checks bestanden:
Auf GitHub:
- Klicken Sie auf “Merge pull request”
- Wählen Sie Merge-Strategie:
- Merge commit: Behält alle Commits (Standard)
- Squash and merge: Kombiniert alle Commits zu einem
- Rebase and merge: Spielt Commits auf main ab
- Klicken Sie auf “Confirm merge”
- Erfolg! Ihr Feature ist jetzt in
main
Was passiert:
Vor dem Merge:
main: A → B → C
↘
feature: D → E → F
Nach dem Merge:
main: A → B → C → M (Merge-Commit, enthält D, E, F)
5.10 Schritt 9: Feature Branch löschen
Nach dem Mergen, lösche den Feature Branch:
Auf GitHub:
- Klicken Sie auf “Delete branch” Button (erscheint nach dem Merge)
Lokal:
# Zurück zu main wechseln
$ git checkout main
# Die gemergten Änderungen pullen
$ git pull origin main
# Lokalen Feature Branch löschen
$ git branch -d feature/fix-code-qualityentication
Warum löschen?
- Hält das Repository sauber
- Verhindert Verwirrung (Branch bereits gemerged)
- Branches sind billig—erstelle neue für neue Features
6. Teil 4: Pull Requests erklärt
6.1 Was ist ein Pull Request?
Trotz des Namens ist ein Pull Request tatsächlich ein Merge Request. Sie bitten darum, dass Ihre Änderungen in einen anderen Branch (normalerweise main) gemerged werden.
Warum es “Pull Request” heißt:
Historische Gründe. Sie bitten die Maintainer, Ihre Änderungen in ihr Repository zu “pullen”.
Moderne Interpretation:
“Bitte überprüfe und merge meine Änderungen.”
6.2 Anatomie eines Pull Requests
Ein PR besteht aus:
1. Titel & Beschreibung
- Was der PR macht
- Warum es benötigt wird
- Besondere Überlegungen
2. Commits
- Alle Commits von Ihrem Feature Branch
- Aktualisiert sich automatisch, wenn Sie mehr Commits pushen
3. Files Changed (Diff)
- Visuelle Darstellung dessen, was sich geändert hat
- Zeile-für-Zeile-Vergleich
- Einfach zu überprüfen
4. Conversation
- Diskussions-Thread
- Review-Kommentare
- Genehmigungen/Ablehnungen
5. Checks
- Automatisierte Tests/Linting (wir fügen das in Kapitel 02 (Automatisierung und CI/CD) hinzu!)
- Build-Status
- Code Coverage
6.3 PR Best Practices
Größe ist wichtig:
✅ Guter PR: 50-300 geänderte Zeilen
- Einfach zu überprüfen
- Klarer Zweck
- Weniger wahrscheinlich Bugs
❌ Schlechter PR: 2.000+ geänderte Zeilen
- Überwältigend zu überprüfen
- Wahrscheinlich durchgewunken (ohne echte Review genehmigt)
- Wahrscheinlicher, Bugs einzuführen
Wenn Ihr PR zu groß ist: Teilen Sie ihn in mehrere PRs auf.
Beispiel - Ein großes Feature aufteilen:
Anstatt:
❌ PR #1: "Fix all 14 PEP8 violations at once" (2000 Zeilen über mehrere Dateien)
Mache dies:
✅ PR #1: "Fix PEP8: Separate imports and remove unused ones" (40 Zeilen)
✅ PR #2: "Fix PEP8: Add proper spacing around operators" (50 Zeilen)
✅ PR #3: "Fix PEP8: Rename functions to snake_case" (60 Zeilen)
✅ PR #4: "Fix PEP8: Break long lines to fit 88 character limit" (45 Zeilen)
✅ PR #5: "Fix PEP8: Remove unused variables and functions" (30 Zeilen)
Gute PR-Beschreibungen:
## Was
Behebt alle PEP8-Verstöße, die von Ruff in main.py gefunden wurden.
## Warum
Code-Qualität verbessern und Konformität mit PEP8-Standards sicherstellen (adressiert Kapitel 02 (Code-Qualität in der Praxis) Ruff-Fehler).
## Wie
- Trennte mehrere Imports auf verschiedene Zeilen
- Entfernte ungenutzte sys und os Imports
- Fügte korrektes Spacing um Operatoren hinzu
- Benannte HelperFunction zu helper_function um
## Tests
- Alle Ruff Checks bestehen: `uv run ruff check src/`
- Code-Formatierung verifiziert: `uv run ruff format --check src/`
- Anwendung läuft noch korrekt: `uv run road-profile-viewer`
## Vorher/Nachher
- Vorher: 14 Ruff Fehler
- Nachher: 0 Ruff Fehler ✅
## Checkliste
- [x] Code folgt PEP8 Style Guide
- [x] Alle Ruff Checks bestehen
- [x] Anwendung getestet
- [x] Keine Breaking Changes
6.4 Pull Requests überprüfen
Als Reviewer schaue nach:
1. Funktioniert es?
- Logik ist korrekt
- Edge Cases behandelt
- Keine offensichtlichen Bugs
2. Ist es getestet?
- Unit Tests enthalten
- Edge Cases abgedeckt
- Tests testen tatsächlich das Feature
3. Ist es lesbar?
- Klare Variablennamen
- Gute Kommentare (wenn nötig)
- Folgt Style Guide
4. Ist es wartbar?
- Nicht übermäßig komplex
- Verwendet bestehenden Code wieder
- Dokumentiert, wenn notwendig
Beispiel Review-Kommentar:
# Ihr Code nach Spacing-Korrekturen:
def generate_road_profile(num_points=100, x_max=80):
"""Generate a road profile..."""
x = np.linspace(0, x_max, num_points)
# Review-Kommentar: "Tolle Spacing-Korrekturen! Aber sollten wir hier
# Type Hints hinzufügen? Das würde Pyright glücklich machen und die
# Code-Dokumentation verbessern."
return x, y
6.5 PR-Zustände
Open:
- PR wird überprüft
- Kann noch modifiziert werden
- Noch nicht gemerged
Merged:
- PR akzeptiert und in Ziel-Branch gemerged
- Feature ist jetzt Teil der Hauptcode-Basis
- Branch kann gelöscht werden
Closed:
- PR abgelehnt oder aufgegeben
- Änderungen nicht gemerged
- Kann wiedereröffnet werden, wenn nötig
Draft:
- Work in Progress
- Noch nicht bereit für Review
- Nützlich, um Fortschritt früh zu zeigen
7. Teil 5: Branch Protection - Direktes Pushen verhindern
7.1 Das Problem
Selbst mit Feature Branches und PRs hindert Sie nichts daran, dies zu tun:
$ git checkout main
$ git commit -m "Quick fix"
$ git push origin main # Umgeht den PR-Prozess!
Das macht den gesamten Zweck von Feature Branches zunichte.
7.2 Branch Protection Rules
Branch Protection macht es unmöglich, direkt zu main zu pushen. Sie müssen einen PR verwenden.
Auf GitHub (Repository-Einstellungen):
- Gehen Sie zu Settings → Branches
- Klicken Sie auf “Add branch protection rule”
- Branch name pattern:
main - Aktivieren Sie:
- ✅ Require a pull request before merging
- ✅ Require approvals (mindestens 1 Review)
- ✅ Require status checks to pass (wir fügen CI-Checks in Kapitel 02 (Automatisierung und CI/CD) hinzu!)
- ✅ Do not allow bypassing the above settings (selbst Admins müssen PRs verwenden)
Jetzt, wenn Sie versuchen, direkt zu pushen:
$ git push origin main
remote: error: GH006: Protected branch update failed for refs/heads/main.
remote: error: Cannot push directly to main. Use a pull request.
To github.com:yourname/yourrepo.git
! [remote rejected] main -> main (protected branch hook declined)
error: failed to push some refs to 'github.com:yourname/yourrepo.git'
✅ Mission erfüllt! Sie sind gezwungen, den richtigen Workflow zu verwenden.
7.3 Vorteile von Branch Protection
1. Erzwingt Code Review
- Kein Code erreicht
mainohne Review - Fängt Bugs vor der Produktion ab
2. Erzwingt Qualitätsprüfungen
- Automatisierte Tests müssen bestehen
- Linting/Formatierung muss bestehen
- Type Checks müssen bestehen
3. Verhindert Unfälle
- Kann nicht versehentlich zum falschen Branch pushen
- Schützt vor Force Pushes
4. Audit Trail
- Jede Änderung hat einen PR
- Klare History, wer was genehmigt hat
- Diskussion archiviert
8. Teil 6: Verbindung zu CI/CD (Vorschau auf Kapitel 02)
8.1 Wo wir jetzt sind
Sie verstehen jetzt:
- ✅ Gits drei Zustände (Working Directory, Staging, Commits)
- ✅ Branches und warum sie wichtig sind
- ✅ Feature Branch Workflow
- ✅ Pull Requests als Code Review-Mechanismus
- ✅ Branch Protection zur Durchsetzung des PR-Workflows
Aber uns fehlt noch die Automatisierung!
8.2 Was als Nächstes in Kapitel 02 kommt
Im nächsten Teil dieser Vorlesung fügen wir GitHub Actions hinzu, um automatisch Checks bei jedem PR durchzuführen:
# .github/workflows/quality.yml
name: Code Quality
on:
pull_request: # ← Trigger bei PRs (nicht bei Pushes zu main!)
branches:
- main
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v4
- run: uv sync --dev
- run: uv run ruff check .
- run: uv run ruff format --check .
- run: uv run pyright
Was das bewirken wird:
Wenn Sie einen PR öffnen, führt GitHub automatisch aus:
- ✅ Ruff Linter
- ✅ Code-Formatierungsprüfung
- ✅ Pyright Type Checker
- ✅ Zeigt Ergebnisse direkt auf dem PR
- ❌ Blockiert Merge, wenn Checks fehlschlagen
Das ist die Kraft von CI/CD:
Entwickler erstellt PR
↓
GitHub Actions läuft automatisch
↓
Alle Checks bestanden ✅
↓
Reviewer sieht: "Sicher zu überprüfen, Checks bestanden"
↓
Genehmigen und mergen
8.3 Der vollständige professionelle Workflow
Feature Branches + PRs + automatisierte Checks kombinieren:
1. Feature Branch von main erstellen
2. Feature implementieren (kleine Commits)
3. Branch zu GitHub pushen
4. Pull Request öffnen
↓
5. Automatisierte Checks laufen (GitHub Actions)
✅ Ruff Linter
✅ Ruff Formatter
✅ Pyright Type Checker
✅ Unit Tests (falls vorhanden)
↓
6. Wenn Checks fehlschlagen ❌
→ Probleme beheben
→ Nochmal pushen (PR aktualisiert sich)
→ Checks laufen erneut
↓
7. Wenn Checks bestehen ✅
→ Review anfordern
→ Feedback adressieren
→ Genehmigung erhalten
↓
8. Zu main mergen (nur möglich, wenn Checks bestehen + genehmigt)
9. Feature Branch löschen
So liefern professionelle Teams hochwertigen Code.
9. Teil 7: Praktische Übung - Ihr erster Feature Branch
9.1 Übung: Füge ein neues Feature mit Feature Branch Workflow hinzu
Szenario: Fügen Sie eine “Kontakt-E-Mail” zur Road Profile Viewer README hinzu.
Folgen Sie dem vollständigen Workflow:
Schritt 1: Von main starten
$ git checkout main
$ git pull origin main
Schritt 2: Feature Branch erstellen
$ git checkout -b feature/add-contact-email
Schritt 3: Machen Sie Ihre Änderung
Bearbeiten Sie README.md:
## Kontakt
Für Fragen oder Feedback, kontaktiere: your.email@example.com
Schritt 4: Committen Sie Ihre Änderung
$ git status
$ git add README.md
$ git commit -m "Add contact email to README"
Schritt 5: Zu GitHub pushen
$ git push -u origin feature/add-contact-email
Schritt 6: Pull Request auf GitHub öffnen
- Gehen Sie zu Ihrem Repository auf GitHub
- Klicken Sie auf “Compare & pull request”
- Füllen Sie Titel aus: “Add contact email to README”
- Füllen Sie Beschreibung aus:
Fügt Kontakt-E-Mail zur README für Benutzer-Feedback hinzu. - Klicken Sie auf “Create pull request”
Schritt 7: Überprüfen Sie Ihren eigenen PR
- Schauen Sie auf den “Files changed” Tab
- Sehen Sie Ihre Änderungen hervorgehoben
- Prüfen Sie, dass nur README.md geändert wurde
Schritt 8: Mergen
(Da dies eine einfache Änderung ist und Sie alleine arbeiten)
- Klicken Sie auf “Merge pull request”
- Klicken Sie auf “Confirm merge”
- Klicken Sie auf “Delete branch”
Schritt 9: Lokal aufräumen
$ git checkout main
$ git pull origin main
$ git branch -d feature/add-contact-email
Schritt 10: Verifizieren
$ git log --oneline
# Sie sollten Ihre Commit Message in der History sehen
Glückwunsch! Sie haben gerade Ihren ersten professionellen Feature Branch Workflow abgeschlossen.
9.2 Übungs-Checkliste
Haben Sie:
- ✅ Von einem aktuellen
mainBranch gestartet? - ✅ Einen beschreibenden Feature Branch-Namen erstellt?
- ✅ Eine fokussierte Änderung gemacht?
- ✅ Eine klare Commit Message geschrieben?
- ✅ Zu GitHub gepusht?
- ✅ Einen Pull Request geöffnet?
- ✅ Erst nach Review gemerged?
- ✅ Den Feature Branch nach dem Mergen gelöscht?
Wenn ja zu allem: Sie denken wie ein professioneller Entwickler!
10. Teil 8: Häufige Workflows und Befehls-Referenz
10.1 Tägliche Workflow-Befehle
Ein neues Feature starten:
git checkout main
git pull origin main
git checkout -b feature/my-new-feature
Beim Arbeiten:
git status # Prüfen, was sich geändert hat
git diff # Genaue Änderungen sehen
git add <file> # Spezifische Datei stagen
git add . # Alle Änderungen stagen
git commit -m "Message" # Gestagete Änderungen committen
Änderungen pushen:
git push -u origin feature/my-new-feature # Erster Push
git push # Nachfolgende Pushes
Ein Feature beenden:
# (Merge via PR auf GitHub)
git checkout main
git pull origin main
git branch -d feature/my-new-feature
10.2 Nützliche Git-Befehle
Informations-Befehle:
git status # Aktueller Zustand
git log --oneline --graph --all # Visuelle Commit History
git branch # Branches auflisten
git diff # Nicht gestagete Änderungen
git diff --staged # Für Commit gestagete Änderungen
git show <commit-hash> # Details eines spezifischen Commits
Änderungen rückgängig machen:
git restore <file> # Änderungen im Working Directory verwerfen
git restore --staged <file> # Datei unstagen (Änderungen behalten)
git reset HEAD~1 # Letzten Commit rückgängig machen (Änderungen behalten)
git commit --amend # Letzte Commit Message ändern
Branch-Verwaltung:
git branch # Lokale Branches auflisten
git branch -a # Alle Branches auflisten (inkl. Remote)
git branch -d <branch> # Gemergten Branch löschen
git branch -D <branch> # Branch erzwungen löschen
10.3 Häufige Git-Szenarien
Szenario 1: Ich habe zum falschen Branch committed!
# Wenn Sie noch nicht gepusht haben:
git reset HEAD~1 # Commit rückgängig, Änderungen behalten
git checkout correct-branch
git add .
git commit -m "Message"
Szenario 2: Ich muss meinen Feature Branch mit neuestem main aktualisieren
git checkout feature/my-feature
git pull origin main # Main in Feature Branch mergen
# Konflikte lösen, falls vorhanden
git push
Szenario 3: Ich möchte bei dieser Datei von vorne anfangen
git checkout <file> # Alle Änderungen an Datei verwerfen
Szenario 4: Ich habe vergessen, einen Feature Branch zu erstellen
# Wenn Sie noch nicht committed haben:
git stash # Änderungen temporär speichern
git checkout -b feature/new-feature # Branch erstellen
git stash pop # Änderungen wiederherstellen
git add .
git commit -m "Message"
10.4 Aufräumen: Remote-Tracking Branches verstehen
Warum das wichtig ist:
Nachdem Sie mehrere PRs gemergt haben, werden Sie feststellen, dass Ihr lokales Repository noch Referenzen zu Branches hat, die auf GitHub gelöscht wurden. Das Verstehen von Remote-Tracking Branches hilft Ihnen, Ihr Repository sauber und organisiert zu halten.
Die drei Arten von Branches
Git verwaltet tatsächlich drei separate Arten von Branches:
- Lokale Branches (auf Ihrem Computer):
git branch # Beispielausgabe: # * main # feature/add-quiz-exportDies sind Ihre eigenen Branches - Arbeitsbereiche, die nur auf Ihrem Computer existieren, bis Sie sie pushen.
- Remote-Tracking Branches (ebenfalls auf Ihrem Computer, aber verfolgen GitHub):
git branch -r # Beispielausgabe: # remotes/origin/main # remotes/origin/feature/add-quiz-export # remotes/origin/feature/hide-quiz-answers # ⚠️ Auf GitHub gelöscht, aber hier noch sichtbar!Dies sind lokale Referenzen, die verfolgen, was auf GitHub existiert. Sie werden mit
remotes/origin/vorangestellt. - Remote Branches (auf GitHub):
- Die tatsächlichen Branches auf dem GitHub-Server
- Nicht direkt mit
git branchsichtbar (müssen GitHub.com besuchen)
Die Lesezeichen-Analogie
Denken Sie an Remote-Tracking Branches wie Lesezeichen in Ihrem Browser:
- GitHub = Die tatsächlichen Websites
- Remote-Tracking Branches = Ihre Lesezeichen, die auf GitHubs Branches zeigen
- Lokale Branches = Ihre eigenen Notizen/Entwürfe (getrennt von Lesezeichen)
Was passiert, wenn ein Branch auf GitHub gelöscht wird:
1. Sie mergen PR #58 auf GitHub
→ GitHub löscht feature/hide-quiz-answers
2. Ihr Remote-Tracking Branch (Lesezeichen) zeigt noch auf ihn
→ remotes/origin/feature/hide-quiz-answers existiert noch lokal
3. Das ist wie ein kaputtes Lesezeichen
→ Die Website (GitHub Branch) ist weg, aber Ihr Lesezeichen bleibt
Warum veraltete Referenzen entstehen
Szenario: Sie haben gerade 5 PRs gemergt
# Auf GitHub (nach Mergen von PRs):
✅ feature/add-quiz-export → Gemergt und gelöscht
✅ feature/hide-quiz-answers → Gemergt und gelöscht
✅ feature/add-exercise-link → Gemergt und gelöscht
✅ feature/show-quiz-answers → Gemergt und gelöscht
✅ feature/add-divergence-docs → Gemergt und gelöscht
# Ihre lokalen Remote-Tracking Branches (ohne Bereinigung):
$ git branch -r
remotes/origin/main
remotes/origin/feature/add-quiz-export # ⚠️ Existiert nicht mehr auf GitHub!
remotes/origin/feature/hide-quiz-answers # ⚠️ Existiert nicht mehr auf GitHub!
remotes/origin/feature/add-exercise-link # ⚠️ Existiert nicht mehr auf GitHub!
remotes/origin/feature/show-quiz-answers # ⚠️ Existiert nicht mehr auf GitHub!
remotes/origin/feature/add-divergence-docs # ⚠️ Existiert nicht mehr auf GitHub!
Warum passiert das?
git fetchfügt neue Remote-Tracking Branches hinzu, aber löscht veraltete nicht automatischgit pull(das istfetch+merge) hat dasselbe Verhalten- Ihre lokalen “Lesezeichen” bleiben, auch nachdem die GitHub-Branches weg sind
Die Lösung: git fetch --prune
Option 1: Bereinige während des Fetchens (empfohlen)
git fetch --prune
Das bedeutet:
- ✅ Lade neue Branches/Commits von GitHub herunter
- ✅ Aktualisiere bestehende Remote-Tracking Branches
- ✅ Lösche Remote-Tracking Branches, die auf GitHub nicht mehr existieren
Option 2: Bereinige explizit ohne Fetchen
git remote prune origin
Dies macht nur Schritt 3 - löscht veraltete Remote-Tracking Branches, ohne neue Daten zu fetchen.
Der vollständige Bereinigungs-Workflow
Nach dem Mergen eines PRs und dem Löschen des Branches auf GitHub:
# Schritt 1: Wechsle zu main und aktualisiere ihn (mit automatischer Bereinigung)
git checkout main
git pull --prune
# Schritt 2: Löschen Sie Ihren lokalen Feature Branch
git branch -d feature/my-merged-feature
Warum diese Schritte?
git checkout mainwechselt zu Ihrem lokalen main Branch (auch wenn er veraltet ist)git pull --prunemacht DREI Dinge auf einmal:- Fetcht Updates von GitHub (aktualisiert
origin/mainLesezeichen) - Mergt diese Updates in Ihren lokalen main (bewegt main-Pointer vorwärts)
- Entfernt veraltete Remote-Tracking Branches (wie
remotes/origin/feature/my-merged-feature)
- Fetcht Updates von GitHub (aktualisiert
git branch -dentfernt Ihre lokale Arbeitskopie des Branches
Den Workflow verstehen:
Vor der Bereinigung:
GitHub main: A---B---C---D---E (Ihr PR wurde hier gemergt)
origin/main: A---B---C (veraltetes Lesezeichen)
local main: A---B---C (hier sind Sie nach checkout)
Nach git pull --prune:
GitHub main: A---B---C---D---E
origin/main: A---B---C---D---E (Lesezeichen aktualisiert!)
local main: A---B---C---D---E (fast-forward!)
Hinweis: git pull --prune kombiniert git fetch --prune + git merge origin/main in einem Befehl!
Automatisches Pruning konfigurieren
Um veraltete Referenzen in Zukunft zu vermeiden:
# Konfiguriere Git, um automatisch bei jedem fetch zu bereinigen
git config --global fetch.prune true
Jetzt wird bei jedem git fetch oder git pull automatisch bereinigt! 🎉
Häufige Szenarien
Szenario 1: Branch wurde gemergt, aber Git sagt “nicht vollständig gemergt”
$ git branch -d feature/my-feature
error: The branch 'feature/my-feature' is not fully merged.
# Das passiert, wenn GitHub Squash oder Rebase Merge verwendet hat
# Die Commits sind anders, aber der Inhalt ist in main
# Lösung: Erzwingen Sie Löschen (sicher, wenn Sie wissen, dass er gemergt ist)
$ git branch -D feature/my-feature
Szenario 2: Batch-Bereinigung aller gemergten Branches
# Liste alle Branches, die in main gemergt sind
git branch --merged main
# Lösche alle gemergten Branches außer main
git branch --merged main | grep -v "main" | xargs git branch -d
Visuelle Zusammenfassung
GitHub (Remote)
│
│ git push
│
▼
┌─────────────────────────┐
│ feature/my-feature │
│ (Remote Branch) │
└─────────────────────────┘
│
│ git fetch
│
▼
┌───────────────────────────────────┐
│ remotes/origin/feature/my-feature │ ◄── Remote-Tracking Branch
│ (Lokale Referenz zu GitHub) │ (Ihr "Lesezeichen")
└───────────────────────────────────┘
│
│ git checkout
│
▼
┌─────────────────────────┐
│ feature/my-feature │ ◄── Lokaler Branch
│ (Lokaler Branch) │ (Ihre Arbeit)
└─────────────────────────┘
Nach PR Merge auf GitHub:
═══════════════════════════════
GitHub löscht: feature/my-feature
│
▼
Ohne --prune:
remotes/origin/feature/my-feature ← ⚠️ Noch da! (veraltetes Lesezeichen)
feature/my-feature ← ⚠️ Noch da! (lokaler Branch)
│
▼
Mit --prune:
remotes/origin/feature/my-feature ← ✅ Gelöscht! (Lesezeichen entfernt)
feature/my-feature ← ⚠️ Noch da (müssen manuell löschen: git branch -d)
Schnellreferenz: Bereinigungs-Befehle
# Veraltete Remote-Tracking Branches anzeigen
git remote prune origin --dry-run
# Veraltete Remote-Tracking Branches löschen
git fetch --prune # Empfohlen: fetch + prune
git remote prune origin # Alternative: nur prune
# Gemergten lokalen Branch löschen
git branch -d branch-name # Sicher (fehlschlägt, wenn nicht gemergt)
git branch -D branch-name # Erzwinge (verwende mit Vorsicht!)
# Alle Branches anzeigen
git branch # Lokale Branches
git branch -r # Remote-Tracking Branches
git branch -a # Alle (lokal + remote-tracking)
# Automatisches Pruning konfigurieren (einmal ausführen)
git config --global fetch.prune true
Wichtigste Erkenntnis:
- Remote-Tracking Branches sind lokale Lesezeichen zu GitHub-Branches
git fetch --prunehält diese Lesezeichen mit der Realität synchronisiert- Sie müssen dennoch manuell lokale Branches mit
git branch -dlöschen - Halten Sie Ihr Repository sauber = glücklicheres Git-Erlebnis! ✨
11. Zusammenfassung: Von Cowboy Coding zu professionellen Workflows
11.1 Was Sie gelernt haben
Git-Grundlagen:
- ✅ Drei Zustände: Working Directory → Staging Area → Repository
- ✅ Commits als Snapshots Ihres Projekts
- ✅ Branches als parallele Entwicklungslinien
- ✅ Warum die Staging Area existiert (Kontrolle über Commits)
Feature Branch Workflow:
- ✅ Pushe niemals direkt zu
main - ✅ Erstelle Feature Branches für alle Änderungen
- ✅ Verwende beschreibende Branch-Namen
- ✅ Mache kleine, fokussierte Commits
- ✅ Lösche Branches nach dem Mergen
Pull Requests:
- ✅ PRs ermöglichen Code Review vor dem Mergen
- ✅ Halte PRs klein (50-300 Zeilen)
- ✅ Schreibe beschreibende PR-Beschreibungen
- ✅ Adressiere Feedback mit neuen Commits
- ✅ PRs sind Merge Requests, nicht Pull Requests
Branch Protection:
- ✅ Verhindert direktes Pushen zu
main - ✅ Erzwingt PR-Workflow
- ✅ Erfordert Code Review
- ✅ Kann automatisierte Checks erfordern (nächste Vorlesung!)
Professionelle Praktiken:
- ✅ Starte immer von aktuellem
main - ✅ Ein Feature = ein Branch
- ✅ Committe früh, committe oft
- ✅ Schreibe klare Commit Messages
- ✅ Überprüfen Sie Ihre eigenen PRs, bevor Sie andere fragen
11.2 Die Transformation
Vor dieser Vorlesung (Cowboy Coding):
$ git add .
$ git commit -m "stuff"
$ git push origin main # 🔥 Hoffe, nichts geht kaputt!
Nach dieser Vorlesung (Professioneller Workflow):
$ git checkout main
$ git pull origin main
$ git checkout -b feature/fix-code-quality
# ... arbeite am Feature ...
$ git add main.py
$ git commit -m "Fix PEP8: Separate imports onto different lines"
$ git push -u origin feature/fix-code-quality
# ... öffne PR, hole Review, adressiere Feedback ...
# ... merge via PR auf GitHub ...
$ git checkout main
$ git pull origin main
$ git branch -d feature/fix-code-quality
11.3 Warum das wichtig ist
1. Qualität
- Code wird vor dem Mergen überprüft
- Automatisierte Checks stellen Standards sicher (nächste Vorlesung!)
- Main Branch bleibt stabil
2. Zusammenarbeit
- Mehrere Entwickler können gleichzeitig arbeiten
- Niemand tritt anderen auf die Füße
- Klare Kommunikation via PRs
3. Reversibilität
- Einfach schlechte Änderungen rückgängig zu machen
- Klare History, wer was geändert hat
- Branches können aufgegeben werden, ohne main zu beeinflussen
4. Professionalität
- Industrie-Standard-Workflow
- Zeigt, dass Sie moderne Entwicklungspraktiken verstehen
- Macht Sie zu einem besseren Teammitglied
5. Selbstvertrauen
- Experimentiere ohne Angst
- Main Branch ist immer deploybar
- Änderungen sind isoliert, bis sie bewiesen sind
11.4 Vorbereitung auf Kapitel 02
Sie haben jetzt das Fundament für CI/CD:
- ✅ Feature Branches zur Isolation von Änderungen
- ✅ Pull Requests als Qualitätsgates
- ✅ Branch Protection zur Durchsetzung des Workflows
Nächste Vorlesung fügen wir Automatisierung hinzu:
- GitHub Actions, um Checks automatisch durchzuführen
- Automatisiertes Linting, Formatierung, Type Checking
- Merge blockieren, wenn Qualitätsprüfungen fehlschlagen
- Ergebnisse direkt auf PRs sehen
Das vollständige Bild:
Feature Branch → PR → Automatisierte Checks → Code Review → Merge
↑
Das bauen wir als Nächstes!
12. Wichtigste Erkenntnisse
Merken Sie sich diese Prinzipien:
- Pushe niemals direkt zu
main- Verwende immer Feature Branches - Branches sind billig - Erstelle einen neuen Branch für jedes Feature/jeden Fix
- Commits sind permanent - Schreibe klare Commit Messages
- PRs ermöglichen Zusammenarbeit - Verwenden Sie sie für alle Änderungen, auch wenn Sie alleine arbeiten
- Kleine PRs sind besser - 50-300 Zeilen sind ideal
- Branch Protection ist essentiell - Erzwingen Sie Ihren Workflow mit Regeln
- Starten Sie von aktuellem
main- Pullen Sie immer, bevor Sie einen Branch erstellen - Löschen Sie gemergte Branches - Halten Sie Ihr Repository sauber
git statusist Ihr Freund - Verwenden Sie es ständig- Feature Branch Workflow ist Industrie-Standard - Lerne ihn jetzt, verwende ihn für immer
Sie sind jetzt bereit, wie ein professioneller Entwickler zu arbeiten!
In Kapitel 02 (Automatisierung und CI/CD) werden wir Qualitätsprüfungen automatisieren, um diesen Workflow noch mächtiger zu machen.
13. Weiterführende Literatur
Offizielle Git-Dokumentation:
- Git Basics - Getting a Git Repository
- Git Branching - Branches in a Nutshell
- Git Branching - Basic Branching and Merging
GitHub-Dokumentation:
Interaktives Lernen:
- Learn Git Branching - Visuelles, interaktives Git-Tutorial
- GitHub Skills - Praxisnahes GitHub-Lernen
Industrie-Praktiken:
- A successful Git branching model (Git Flow)
- GitHub Flow (Einfachere Alternative)