- Verbesserungen von späteren auf frühere Branches zurückportieren, wo sinnvoll
- Nach dem Rebasen immer zum `scripting`-Branch zurückkehren
+### Halbautomatischer Workflow mit `rebase.sh`
+
+Für vollständige Rebases über alle Branches wird `rebase.sh` eingesetzt. Das Skript iteriert alle Branches in der richtigen Reihenfolge (ROOT-Branches zuerst) und rebasiert sie nicht-interaktiv. Bei Konflikten bricht es ab.
+
+**Workflow:**
+
+1. `./rebase.sh` starten.
+2. Bricht das Skript bei einem Branch ab, gilt es zu untersuchen, woran es liegt:
+
+ **Fall A – Duplikat-Commit:** Der scheiternde Commit findet sich bereits mit exakt gleichem Namen im `git log <ROOT>`. Ursache: Ein Commit wurde in einem vorgelagerten Rebase inhaltlich verändert, sein Hash hat sich dadurch geändert, und git erkennt ihn nicht mehr als „bereits enthalten". → Lösung: Duplikat per interaktivem Rebase mit `drop` entfernen (siehe Konfliktmuster „Duplikat-Commits durch Hash-Verschiebung").
+
+ **Fall B – Echter Inhaltskonflikt:** Der scheiternde Commit ist im ROOT-Branch nicht enthalten. → Konflikt manuell auflösen (siehe Wiederkehrende Konfliktmuster), dann `git rebase --continue`.
+
+3. Nach der Auflösung: `git checkout scripting` (das Skript lässt den Branch ausgecheckt — `lib.sh` und `rebase.sh` sind nur auf `scripting` sichtbar) und `./rebase.sh` neu starten. Es läuft über bereits erledigte Branches ohne Aktion hinweg und setzt beim nächsten Problem an.
+
## Live-Codings
Live-Codings verbinden die technischen Lücken zwischen den Übungsgruppen. Jedes Live-Coding zeigt schrittweise die Unterschiede zwischen dem Setup (und den benötigten "off-topic"-Techniken und Boilerplate-Code) in einem gegebenen Ausgangsbranch und einem neuen Zielbranch für die kommenden Übungen.
**Cherry-Pick-Reihenfolge-Konflikte** (späterer umfassender Commit bereits angewendet, früherer einfacherer Commit konfliktiert):
Wenn HEAD bereits die vollständigere Version einer Datei enthält und ein nachfolgender Cherry-Pick versucht, eine frühere, einfachere Version anzuwenden — HEAD behalten. Der frühere Commit fügte nur einen Teil von dem hinzu, was HEAD bereits hat.
+**Duplikat-Commits durch Hash-Verschiebung (Kaskaden-Problem):**
+
+Ursache: Wenn ein Commit während eines Rebases inhaltlich verändert wird (weil eine Konfliktauflösung seinen Inhalt anpasst), ändert sich sein Hash. Git erkennt ihn in Downstream-Branches nicht mehr als „bereits enthalten" und versucht, ihn erneut anzuwenden — was zu Konflikten führt.
+
+Erkennung: Der scheiternde Commit (meist der erste, `1/N` in der Rebase-Liste) findet sich mit **exakt gleichem Namen** bereits im `git log <ROOT>`.
+
+Lösung per `GIT_SEQUENCE_EDITOR`:
+```bash
+# 1. Einmalig pro Session erstellen; alte Hashes nach Bedarf ergänzen:
+cat > /tmp/drop_duplicates.sh << 'EOF'
+#!/bin/bash
+sed -i '/alter_hash_1\|alter_hash_2/d' "$1"
+EOF
+chmod +x /tmp/drop_duplicates.sh
+
+# 2. Duplikat aus dem Branch entfernen (7+ Zeichen des alten Hash genügen):
+GIT_SEQUENCE_EDITOR=/tmp/drop_duplicates.sh git rebase -i <root> <branch>
+```
+
+**Kaskadierung:** Wenn der Rebase von Branch P einen Commit inhaltlich verändert, müssen alle Kinder-Branches von P den alten Hash droppen. Haben diese Kinder-Branches ihrerseits branch-spezifische Commits (z.B. Versions-Commit), die durch ihren Rebase ebenfalls verändert werden, müssen deren alte Hashes für die Enkel-Branches ebenfalls in den Filter. Den Filter in `/tmp/drop_duplicates.sh` mit wachsender Tiefe des Baums erweitern. Falls nach dem Drop weitere Konflikte auftreten (meist Versions-Konflikte in `pom.xml`/`build.gradle`): Python-Einzeiler aus dem Versions-Konflikt-Muster oben anwenden, dann `git rebase --continue`.
+
+**Modify/Delete-Konflikte (reine Infrastruktur-Branches):**
+Löscht ein eingehender Commit eine Datei, die HEAD noch (modifiziert) enthält — z.B. wenn ein Branch die Java-Codebasis vollständig durch Docker-only-Setup ersetzt:
+```bash
+git rm <datei>
+git rebase --continue
+```
+
+**Konflikte durch Erweiterungen im ROOT-Branch:**
+Wenn eine neue Funktion in einem ROOT-Branch eingeführt wird (z.B. `ConsumerRebalanceListener` in `grundlagen/simple-consumer`), die ein Downstream-Branch bewusst nicht enthält, kann der erste einzigartige Commit des Downstream-Branches konfligieren: HEAD enthält die neue Funktion, aber der Commit wurde gegen die alte Basis ohne sie geschrieben.
+
+Auflösung: Das Ziel des Downstream-Branches bestimmt die Lösung. Den korrekten Endzustand aus dem (noch nicht rebasiserten) Original-Branch holen:
+```bash
+git show <branch-name>:src/.../Datei.java > src/.../Datei.java
+git add src/.../Datei.java
+git rebase --continue
+```
+Für `--livecoding--schritte`-Branches: `git checkout --theirs -- <datei>` (nimmt die Version des eingehenden Commits) ist oft die richtige Wahl, um den Schritt so zu reformulieren, dass er im neuen Kontext den richtigen Übergang demonstriert.
+
### Bibliotheks-Branches
Wandelt ein Branch die Anwendung in eine **reine Java-Bibliothek** um (keine Spring-Boot-App, z.B. `sumup-messages--vorlage`), ist die gesamte Spring-Boot-Deployment-Infrastruktur aus den Build-Dateien zu entfernen: