Von Nova Trent, Junior Entwicklerin bei Java Fleet Systems Consulting

Das Wichtigste in 30 Sekunden 🕐
Letzte Woche: Elyndra sagt: „Nova, niemals direkt auf main entwickeln!“
Diese Woche: Ich hab’s versucht. Einen Branch gemacht. Entwickelt. Gemergt.
Ergebnis: 47 Merge-Conflicts und Tränen in den Augen. 😭
ABER: Ich hab’s überlebt! Und jetzt verstehe ich endlich warum Branches die Rettung sind – und warum Linus Torvalds Git überhaupt erfunden hat!
In Teil 2 lernst du:
- 🌿 Warum Branches die Lösung für das „Überschreib-Problem“ sind
- 🔥 Die WILDE Geschichte wie Git aus Notwehr entstand
- 🔧 Merge-Conflicts lösen ohne Panik
- 🎯 Branching-Strategien die wirklich funktionieren
- 💪 Vom „Oh Gott, was hab ich gemacht?“ zu „Ich hab das!“
Recap: Wo waren wir? 📚
Falls du Teil 1 verpasst hast: Hier geht’s zu Teil 1 meiner ersten Serie!
Was wir letzte Woche gelernt haben:
- ✅ Git-Grundlagen (Working Directory, Staging Area, Repository)
- ✅ Die wichtigsten Kommandos (add, commit, push, pull)
- ✅ „Gestern lief es noch“ ist keine Ausrede mehr!
- ✅ Git ≠ GitHub (funktioniert komplett offline!)
- ✅ git reflog rettet fast alles
Diese Woche wird’s ernst: Wir arbeiten im Team. Mit Branches. Und da fängt das Chaos an… 😅
Die WAHRE Geschichte: Warum Linus Git erfunden hat 🔥
Bevor ich euch meine Branch-Katastrophe zeige, MÜSST ihr diese Story hören!
Letzte Woche hab ich Dr. Cassian gefragt: „Warum gibt es Git überhaupt? Warum reichte CVS oder SVN nicht?“
Seine Antwort hat mich umgehauen! 🤯
Linus Torvalds und die „Blödmänner“
Die Situation: 2005, Linux-Kernel-Entwicklung
Das Problem:
Linus arbeitet an Datei X (mit CVS)
↓
Anderer Entwickler ändert DIESELBE Datei
↓
Beide pushen gleichzeitig
↓
💥 Linus' Code wird überschrieben!
↓
Linus: "SCHON WIEDER?! Wer war das?!"
Cassian’s Erklärung:
„Nova, Linus wurde ständig von anderen Entwicklern überschrieben. Er nannte diese Leute intern ‚GITs‘ – britisches Slang für ‚Blödmänner‘ oder ‚unpleasant persons‘. Das war sein Spitzname für alle, die versehentlich seine Arbeit zerstörten!“
Ich dachte erst, er macht Witze. Aber nein – das ist ECHT! 😂
Was Linus so genervt hat:
CVS/SVN (die alten Systeme):
Zentraler Server
↓
ALLE ändern direkt
↓
Wer zuletzt pusht, gewinnt
↓
Code von anderen = ÜBERSCHRIEBEN
↓
"Letzter wins" = Lost Code 💀
Das Chaos:
- Du entwickelst 3 Stunden an Feature A
- Jemand pusht in der Zeit seine Änderung
- Du pushst deine Änderung
- Seine Arbeit? WEG! (Oder deine, je nachdem wer zuletzt kam)
Linus‘ Reaktion: „Das ist WAHNSINN! Ich brauch ein System wo das UNMÖGLICH ist!“
Git’s geniale Lösung: Branches!
Linus‘ Idee:
JEDER arbeitet in SEINEM Branch
↓
Niemand kann niemanden überschreiben
↓
Merge NUR wenn beide bereit sind
↓
Conflicts? Git ZWINGT dich sie zu lösen!
↓
"Niemand verliert Code" ✅
Das ist der Grund warum Git Branches hat! Nicht als „nice Feature“ – sondern als Überlebensnotwendigkeit!
Fun Facts über Git’s Entstehung:
1. Der Name „Git“: Linus selbst sagte:
„I’m an egotistical bastard, and I name all my projects after myself. First ‚Linux‘, now ‚Git‘.“
„Git“ = britisches Slang für „Depp“ oder „Blödmann“! 😂
2. Die Geschwindigkeit: Linus hat Git in 2 WOCHEN gebaut! Warum? Er war SO genervt, dass er sagte: „Ich bau das jetzt einfach selbst!“
3. Das Ziel: „I want a system where nobody can f*** up anyone else’s work anymore!“ (Cassian’s Übersetzung: „Ein System wo Blödmänner keinen Schaden mehr anrichten können!“)
Nova’s Aha-Moment: 🤯 Jedes Mal wenn ich jetzt einen Branch erstelle, denke ich: „Danke Linus, dass du so genervt warst! Ohne die ‚Blödmänner‘ hätten wir kein Git!“
Und jetzt verstehe ich: Branches sind nicht kompliziert – sie sind SCHUTZ! Schutz vor versehentlichem Überschreiben. Schutz vor „Blödmännern“ (auch wenn ich selbst manchmal einer bin 😅).
Warum „main“ heilig ist – Elyndras Lektion 📜
Montag, 14:30 Uhr: Ich entwickle direkt auf main.
Elyndra schaut auf meinen Screen: „Nova… was machst du da?“
Ich: „Äh… Code schreiben?“
Elyndra: „Auf main?! DIREKT auf main?!“
Die goldene Regel:
„main ist Production. main ist heilig. main ist NICHT dein Playground!“ – Elyndra
Warum?
- main = Produktiv-Code → Das läuft beim Kunden!
- Andere entwickeln parallel → Chaos garantiert!
- Bugs auf main → ALLE sind betroffen!
- Rollback schwierig → Wenn was schiefgeht
Die richtige Way: Feature Branches!
# FALSCH (das hab ich gemacht 😅) git checkout main # ... Code ändern auf main git commit -am "Added feature" git push origin main # 💥 EVERYONE is affected! # RICHTIG (das sollte ich tun) git checkout -b feature/user-login # ... Code ändern im Branch git commit -am "Add user login" git push origin feature/user-login # ✅ Nur ICH bin betroffen
Elyndra’s Erklärung:
„Nova, stell dir vor: main ist die Hauptstraße. Dein Branch ist eine Nebenstraße wo du experimentieren kannst. Läuft’s schief? Egal, nur deine Nebenstraße ist gesperrt. Die Hauptstraße läuft weiter!“
Mind = Blown! 🤯 Genau DAS wollte Linus mit Git erreichen!
Mein erster Feature-Branch – Live Disaster! 🎬
Montag, 15:00 Uhr: Ich hab’s verstanden. Ich mache einen Branch!
Schritt 1: Branch erstellen
# Okay, ein Branch für mein Login-Feature git checkout -b feature/user-login # Check: Bin ich wirklich im neuen Branch? git branch # * feature/user-login ← Das Sternchen zeigt wo ich bin! # main
✅ Erfolg! Ich bin in meinem eigenen Branch!
Schritt 2: Code entwickeln
# UserController.java erstellen
echo "public class UserController { }" > UserController.java
# Änderungen stagen und committen
git add UserController.java
git commit -m "Add UserController skeleton"
# Login-Logik hinzufügen
# ... (mehrere Änderungen)
git commit -am "Implement login logic"
# Validation hinzufügen
# ... (noch mehr Änderungen)
git commit -am "Add input validation"
Nova’s Feeling: „Wow, das ist ja easy! Ich committe fleißig, niemand sieht’s auf main. Perfekt!“ 😊
Schritt 3: Zurück zu main und mergen (hier geht’s los… 😰)
# Erstmal checken was auf main passiert ist git checkout main # Updates vom Remote holen git pull origin main
💥 GIT ZEIGT MIR:
remote: Counting objects: 47, done. remote: Compressing objects: 100% (35/35), done. remote: Total 47 (delta 20), reused 0 (delta 0) Unpacking objects: 100% (47/47), done. From gitlab.com:javafleet/task-manager abc1234..def5678 main -> origin/main Updating abc1234..def5678 Fast-forward UserController.java | 25 +++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-)
Mein Gedanke: „Hm, okay… andere haben auch gearbeitet. Kein Problem, ich merge jetzt einfach!“
Schritt 4: Der Merge (und mein erstes Trauma 😱)
# Versuchen zu mergen git merge feature/user-login
💥💥💥 GIT EXPLODIERT:
Auto-merging UserController.java CONFLICT (content): Merge conflict in UserController.java Auto-merging pom.xml CONFLICT (content): Merge conflict in pom.xml Automatic merge failed; fix conflicts and then commit the result.
Ich: „WAAAAAS?! CONFLICT?! WAS BEDEUTET DAS?!“ 😱
git status sagt:
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: UserController.java
both modified: pom.xml
Panik-Modus aktiviert! 🚨
Merge-Conflicts verstehen – Was passiert da?! 🤔
Ich ruf Elyndra: „HILFE! Git sagt CONFLICT! Hab ich was kaputt gemacht?!“
Elyndra (total ruhig): „Nova, relax. Das ist normal. Lass mich erklären…“
Was ist ein Merge-Conflict?
Einfache Erklärung:
Du änderst Zeile 10: "Login mit Email"
↑
Elyndra ändert Zeile 10: "Login mit Username"
↓
Git sagt: "Äh... welche Version soll ich nehmen?!"
Git kann nicht entscheiden! Es braucht dich um zu sagen: „Nimm diese Version!“
Die Conflict-Markierungen verstehen:
Git zeigt das so in der Datei:
public class UserController {
<<<<<<< HEAD (main)
public String loginWithUsername(String username, String password) {
// Elyndra's Version
=======
public String loginWithEmail(String email, String password) {
// Nova's Version
>>>>>>> feature/user-login
return "success";
}
}
Was bedeutet das?
<<<<<<< HEAD→ Das ist die Version auf main (Elyndra’s)=======→ Trenner zwischen beiden Versionen>>>>>>> feature/user-login→ Das ist DEINE Version (Nova’s)
Du musst entscheiden: Welche Version ist richtig? Oder beide kombinieren?
Merge-Conflicts lösen – Step by Step! 🛠️
Elyndra führt mich durch:
Schritt 1: Dateien identifizieren
git status # Unmerged paths zeigt die Dateien mit Conflicts: # both modified: UserController.java # both modified: pom.xml
Nova’s Strategie: „Eine Datei nach der anderen!“
Schritt 2: Datei öffnen und Conflict finden
# In VS Code öffnen code UserController.java
VS Code zeigt mir:
- 🔴 Rot: Conflicts (die <<<< ==== >>>> Marker)
- Buttons: „Accept Current Change“ | „Accept Incoming Change“ | „Accept Both“
Elyndra: „Nova, klick NICHT blind auf die Buttons! Verstehe erst WAS da steht!“
Schritt 3: Entscheiden + Bearbeiten
Mein Konflikt:
<<<<<<< HEAD
public String loginWithUsername(String username, String password) {
=======
public String loginWithEmail(String email, String password) {
>>>>>>> feature/user-login
Meine Analyse:
- Elyndra hat Username-Login implementiert
- Ich hab Email-Login implementiert
- Wir brauchen BEIDE!
Meine Lösung:
// Conflict-Marker LÖSCHEN und beide Methoden behalten:
public String loginWithUsername(String username, String password) {
// Username-Login
return authService.authenticateByUsername(username, password);
}
public String loginWithEmail(String email, String password) {
// Email-Login
return authService.authenticateByEmail(email, password);
}
✅ Conflict gelöst! Beide Features funktionieren jetzt!
Schritt 4: Änderungen stagen
# Datei als "resolved" markieren git add UserController.java # Status prüfen git status # On branch main # All conflicts fixed but you are still merging. # (use "git commit" to conclude merge)
Schritt 5: Merge-Commit erstellen
git commit -m "Merge feature/user-login: Combine username and email login"
🎉 GESCHAFFT! Mein erster erfolgreicher Merge-Conflict-Resolution!
Merge vs. Rebase – Der Glaubenskrieg 🥊
Nach meinem erfolgreichen Merge fragt Elyndra: „Nova, kennst du Rebase?“
Ich: „Was ist das?!“
Zwei Wege um Branches zusammenzuführen:
1. Merge (was ich gerade gemacht hab):
git merge feature/user-login
Ergebnis:
main: A---B---C-------M
\ /
feature: D---E
- Erzeugt einen Merge-Commit (M)
- Historie zeigt: „Hier wurden zwei Branches zusammengeführt“
- Alle Commits bleiben erhalten
2. Rebase (die „sauberere“ Variante):
git rebase main
Ergebnis:
main: A---B---C---D'---E'
- Keine Merge-Commits
- Sieht aus als hätte man linear entwickelt
- Commits werden „umgeschrieben“ (D‘ und E‘ sind neue Commits!)
Wann was nutzen?
Elyndra’s Regel:
MERGE nutzen wenn: ✅ Feature-Branch → main (Team sieht History) ✅ Du willst zeigen WO Branches zusammenkamen ✅ Du mit anderen zusammenarbeitest REBASE nutzen wenn: ✅ Du deine eigene Branch aufräumen willst ✅ Du lineare History bevorzugst ✅ Feature-Branch noch nicht gepusht (nur lokal!)
⚠️ GOLDENE REGEL:
„Never rebase public branches!“ – Elyndra
Warum? Rebase ändert die History. Wenn andere schon deinen Branch haben → CHAOS!
Code Sentinel’s Tipp:
„Nova, Merge ist sicherer. Rebase ist schöner. Als Anfänger: Bleib bei Merge. Später kannst du Rebase für deine lokalen Branches nutzen.“
Branch-Naming-Conventions – So verlierst du nicht den Überblick 📛
Nach meinem ersten Branch fragt Franz-Martin: „Nova, warum heißt dein Branch feature/user-login?“
Ich: „Weil… Elyndra das so gesagt hat?“
Franz-Martin: „Richtig! Es gibt eine Convention!“
Standard Branch-Präfixe:
feature/... → Neue Features bugfix/... → Bug-Fixes hotfix/... → Dringende Fixes für Production refactor/... → Code-Refactoring (keine neuen Features) docs/... → Dokumentation test/... → Tests hinzufügen
Gute Branch-Namen:
✅ feature/user-authentication ✅ bugfix/login-timeout-error ✅ hotfix/security-vulnerability ✅ refactor/extract-user-service ❌ nova-branch ❌ test ❌ fix ❌ asdf
Warum wichtig?
- Team weiß sofort: Was macht dieser Branch?
- Automation: CI/CD kann Branches nach Typ behandeln
- Übersicht:
git branchzeigt sinnvolle Liste
Nova’s Learning:
VOR dieser Woche:
git branch * nova-test fix-stuff asdf-123 works-now
NACH dieser Woche:
git branch * feature/user-login bugfix/null-pointer-exception refactor/service-layer main
Viel besser! 🎯
Fast-Forward vs. Merge-Commit verstehen 🚄
Beim Mergen hat Git mir zweimal was Unterschiedliches gezeigt:
Versuch 1:
git merge feature/simple-fix # Fast-forward
Versuch 2:
git merge feature/user-login # Merge made by the 'recursive' strategy.
Ich zu Elyndra: „Was ist der Unterschied?!“
Fast-Forward Merge:
Situation:
main: A---B
\
feature: C---D
Niemand hat auf main gearbeitet! Git kann einfach main „vorspulen“:
main: A---B---C---D (einfach weiterschieben!)
Kommando:
git merge feature/simple-fix # Updating abc123..def456 # Fast-forward
Kein Merge-Commit nötig! Git bewegt nur den Pointer.
Merge-Commit:
Situation:
main: A---B---C (jemand hat hier gearbeitet!)
\
feature: D---E
Beide Branches haben neue Commits! Git MUSS beide zusammenführen:
main: A---B---C-------M
\ /
feature: D---E---
Kommando:
git merge feature/user-login # Merge made by the 'recursive' strategy.
Ergebnis: Merge-Commit (M) wird erstellt!
Was ist besser?
Elyndra: „Beide sind okay! Fast-Forward ist schöner (lineare History), aber Merge-Commits zeigen die Arbeit explizit.“
Du kannst erzwingen:
# Merge-Commit auch bei Fast-Forward: git merge --no-ff feature/simple-fix # Fast-Forward oder Fehler (kein Merge-Commit): git merge --ff-only feature/user-login
Git-Flow Basics – Wie das Team arbeitet 🏢
Franz-Martin zeigt mir das Team-Board:
main (Production) ↑ develop (Integration) ↑ feature/* (Individual Features)
Das Git-Flow Model:
1. main Branch:
- Production-Code
- Nur stabile Releases
- Jeder Commit = neues Release
2. develop Branch:
- Integration Branch
- Hier kommen alle Features zusammen
- Wird regelmäßig nach main gemergt
3. Feature Branches:
- Von
developabzweigen - Entwicklung isoliert
- Zurück nach
developmergen
4. Hotfix Branches:
- Von
mainabzweigen (Urgent!) - Direkt nach
mainUNDdevelopmergen
Workflow im Team:
# 1. Feature starten git checkout develop git pull git checkout -b feature/user-login # 2. Entwickeln git commit -am "Implement login" git commit -am "Add tests" # 3. Feature fertig → Merge zu develop git checkout develop git pull # Wichtig: Neueste Version holen! git merge feature/user-login # 4. Push git push origin develop # 5. Branch löschen (lokal) git branch -d feature/user-login
Elyndra’s Tipp: „Nova, merk dir: main berührst du NIE direkt. Alles geht über develop!“
Community-Challenge Woche 2: Branch-Naming! 🏆
Letzte Woche habt ihr mir eure Git-Horror-Stories geschickt – DANKE! 🙏
Die besten kommen nächste Woche in den Blog!
Diese Woche will ich wissen:
📧 Schickt mir eure Branch-Naming-Conventions!
Fragen:
- Welche Präfixe nutzt ihr? (feature/, fix/, …?)
- Wie lang sind eure Branch-Namen?
- Nutzt ihr Issue-Nummern im Namen? (z.B.
feature/JIRA-123-user-login) - Habt ihr Team-Rules für Branches?
→ nova.chen@java-developer.online
Die besten Conventions teile ich nächste Woche!
Kategorien:
- 🥇 „Best Convention“ Award
- 😂 „Kreativste Namen“
- 🏢 „Enterprise-Ready“
- 🎯 „Keep it Simple“ Gewinner
Cheat-Sheet Update: Branch & Merge Commands! 📥
Ich hab mein Cheat-Sheet erweitert:
→ Nova’s Git-Survival-Guide v2.0 downloaden
Neu diese Woche:
- ✅ Alle Branch-Kommandos
- ✅ Merge vs. Rebase Entscheidungsbaum
- ✅ Merge-Conflict-Resolution Schritt-für-Schritt
- ✅ Git-Flow Diagramm
- ✅ Branch-Naming-Conventions Beispiele
Bonus: Meine „Merge-Conflict-Panic-Checklist“! 🆘
❓ FAQs
1. Darf ich direkt auf main entwickeln?
Frage: Kann ich nicht einfach schnell einen Fix auf main committen?
Antwort: Nein! Main ist Production. Nutze Feature-Branches. Nur so bist du sicher. 🚫
2. Was bedeutet ein Merge-Conflict?
Frage: Heißt Conflict, dass mein Code kaputt ist?
Antwort: Nein. Git sagt: „Ihr habt beide dieselbe Stelle geändert. Entscheide, welche Version richtig ist.“ Kein Drama, nur Arbeit. ✅
3. Was sind diese <<<<<< Marker?
Frage: Warum sehe ich plötzlich seltsame Zeichen in meinem Code?
Antwort: Das sind Conflict-Markierungen. HEAD = main, >>>>>> = dein Branch. Du musst dich entscheiden (oder beide kombinieren). 🛠️
4. Merge oder Rebase?
Frage: Was ist besser – mergen oder rebasen?
Antwort: Merge = sicher, Team-freundlich. Rebase = linear, aber gefährlich, wenn schon gepusht. Für Anfänger: Merge!
5. Was ist Fast-Forward?
Frage: Warum steht bei manchen Merges „Fast-Forward“?
Antwort: Wenn niemand auf main gearbeitet hat, zieht Git main einfach auf deinen Branch. Kein Merge-Commit nötig. 🚄
6. Wie lösche ich einen Branch sicher?
Frage: Wie entferne ich einen Branch ohne was kaputt zu machen?
Antwort:
git branch -d feature/user-login # lokal löschen
git push origin –delete feature/user-login # remote löschen
git branch -d feature/user-login # lokal löschen git push origin --delete feature/user-login # remote löschen
Erst löschen, wenn er gemergt ist!
🎯 Teaser auf Teil 3
Nächste Woche geht’s weiter: „Git für Anfänger, Teil 3 – Pull Requests & Code Reviews ohne Herzrasen“ 💬
Du lernst:
- ✅ Was ein Pull Request ist (und warum er dein Freund ist)
- ✅ Wie du Code Reviews überlebst (ohne Angst vor Kritik)
- ✅ Teamwork in Git verstehen
Bleib dran – und vergiss nicht: Merge-Conflicts sind Lernmomente, keine Katastrophen! 🚀

