- `consumer/*` — Consumer-fokussierte Übungen (fortgeschritten)
- `springkafka/*` — Spring-Kafka-API-Übungen
-Die Rebase-Elternbeziehungen (ROOTs) sind **ausschließlich** in der ROOT-Tabelle dieser `CLAUDE.md` festgehalten. `branches.sh` enthält nur die Branch-Namen und die Iterationsliste für Skripte.
+Die Branch-Liste (`$BRANCHES`) und die Rebase-Elternbeziehungen (`$BRANCH_ROOT`) sind maschinenlesbar in `lib.sh` definiert. Diese CLAUDE.md spiegelt dieselben Informationen als menschenlesbare Referenz wider — ROOT-Tabelle und `$BRANCH_ROOT` in `lib.sh` müssen immer synchron gehalten werden.
-> **Diese `CLAUDE.md` ist die einzige maßgebliche Quelle für die Branch-Struktur.**
-> Vor dem Start einer Aufgabe keine Git-Erkundungsbefehle ausführen (`git branch -a`, `git tag`, `git log --all` o.ä.) — alle benötigten Informationen zur Branch-Hierarchie und den ROOTs sind hier vollständig dokumentiert.
+> **Maßgebliche Quellen für die Branch-Struktur:**
+> - **`lib.sh`** — maschinenlesbar: `$BRANCHES` (Iterationsliste) und `$BRANCH_ROOT` (ROOT-Map für Rebase-Skript)
+> - **Diese CLAUDE.md** — menschenlesbar: ROOT-Tabelle als Referenz für manuelle Rebase-Entscheidungen
+>
+> Vor dem Start einer Aufgabe keine Git-Erkundungsbefehle ausführen (`git branch -a`, `git tag`, `git log --all` o.ä.) — alle benötigten Informationen zur Branch-Hierarchie und den ROOTs sind in `lib.sh` und dieser CLAUDE.md vollständig dokumentiert.
> Nur die in der ROOT-Tabelle aufgeführten Branches werden aktiv gepflegt. Das Repository enthält weitere historische Branches, die nicht mehr gewartet werden und ignoriert werden sollen.
### Branch-Hierarchie (vollständige ROOT-Tabelle)
### Skripte im `scripting`-Branch
-Alle Skripte binden `lib.sh` ein, das seinerseits `branches.sh` lädt und gemeinsame Funktionen bereitstellt. Alle Skripte unterstützen `--help`.
+Alle Skripte binden `lib.sh` ein, das `$BRANCHES`, `$BRANCH_ROOT` und gemeinsame Funktionen bereitstellt. Alle Skripte unterstützen `--help`.
| Skript | Zweck |
|--------|-------|
-| `branches.sh` | Definiert die Iterationsliste `$BRANCHES` mit allen Branch-Namen als direkte Zeichenketten |
-| `lib.sh` | Shared Library mit `$BRANCH_NAMES`-Array und den Funktionen `find_common_tag_suffixes()` und `reset_branches_to_remote()` |
+| `lib.sh` | Shared Library: definiert `$BRANCHES`, `$BRANCH_ROOT`, `$BRANCH_NAMES` sowie die Funktionen `find_common_tag_suffixes()` und `reset_branches_to_remote()` |
| `push.sh` | Force-pusht alle Branches zu origin; legt bei Bedarf TIMESTAMP-Backup-Tags an; mit `--tag <suffix>` werden alle Branches zusätzlich getaggt und die Tags gepusht; `--force` überschreibt bestehende Tags |
| `reset.sh` | Setzt alle Branches zurück — auf `origin/<branch>` oder auf einen Tag-Stand |
+| `rebase.sh` | Rebasiert alle Branches nicht-interaktiv auf ihren jeweiligen ROOT (aus `$BRANCH_ROOT`); für automatisierte Nutzung — manuelle Rebase-Sessions folgen dem Workflow in dieser CLAUDE.md |
| `diff.sh` | Zeigt Diffs aller Branches an — lokal gegen origin, gegen einen Tag-Stand, oder zwei Tag-Stände gegeneinander |
| `copy.sh` | Kopiert Branches in die Übungsverzeichnisse (`vorlagen/`, `livecoding/`, `spickzettel/`); bereinigt veraltete Verzeichnisse automatisch; optionale `schulung.conf` schränkt die kopierten Branches ein (siehe unten) |
| `schulung.conf.example` | Vorlage für `schulung.conf` — eine Branch-Angabe pro Zeile, `#`-Kommentare erlaubt |
## Einen neuen Übungs-Branch hinzufügen
-Diese beiden Stellen müssen immer gemeinsam aktualisiert werden — sie halten unterschiedliche Informationen:
+Diese beiden Stellen müssen immer gemeinsam aktualisiert werden:
-**In `branches.sh`** (Branch-Name und Iterationsliste):
-1. Variablenname und -wert (Branch-Name) als neue Zeile eintragen.
-2. Variablenname in die `$BRANCHES`-Iterationsliste aufnehmen.
+**In `lib.sh`** (Branch-Name und ROOT-Beziehung):
+1. Branch-Namen in `$BRANCHES` eintragen.
+2. ROOT-Eintrag in `$BRANCH_ROOT` ergänzen.
-**In dieser `CLAUDE.md`** (ROOT-Beziehung):
+**In dieser `CLAUDE.md`** (ROOT-Beziehung als menschenlesbare Referenz):
3. Neuen Eintrag in der ROOT-Tabelle ergänzen (Abschnitt „Branch-Hierarchie").
## Commit-Konventionen
### Allgemeine Prinzipien
-- Branch für Branch in der Reihenfolge arbeiten, wie in `branches.sh` definiert
+- Branch für Branch in der Reihenfolge arbeiten, wie in `$BRANCHES` (in `lib.sh`) definiert
- Zwischen **absichtlichen** Unterschieden (verschiedene Lernziele) und **unbeabsichtigten** Unterschieden (Zeitdruck, vergessene Backports) unterscheiden
- Verbesserungen von späteren auf frühere Branches zurückportieren, wo sinnvoll
- Nach dem Rebasen immer zum `scripting`-Branch zurückkehren
### ROOT eines Branches ermitteln
-Der ROOT jedes Branches steht in der **ROOT-Tabelle in dieser `CLAUDE.md`** (Abschnitt „Branch-Hierarchie"). **Vor jedem Rebase dort nachschlagen** — nicht in `branches.sh` greifen, da die Tabelle hier bereits vollständig und geprüft ist.
+Der ROOT jedes Branches steht in der **ROOT-Tabelle in dieser `CLAUDE.md`** (Abschnitt „Branch-Hierarchie") und maschinenlesbar in `$BRANCH_ROOT` in `lib.sh`. **Vor jedem manuellen Rebase die ROOT-Tabelle nachschlagen** — nicht im Git-Log oder anderswo raten, da einige ROOTs nicht intuitiv sind.
Als Gegencheck lässt sich der ROOT auch aus dem Branch-HEAD ableiten:
```bash
+++ /dev/null
-#!/bin/bash
-set -e
-
-BRANCHES="\
- grundlagen/docker \
- producer/batch-size--vorlage \
- grundlagen/simple-producer \
- grundlagen/simple-producer--vorlage \
- grundlagen/simple-producer--livecoding \
- grundlagen/simple-producer--livecoding--schritte \
- grundlagen/simple-producer--image--vorlage \
- grundlagen/simple-producer--fire+forget--vorlage \
- grundlagen/simple-producer--completablefuture \
- producer/simple-producer--auditheaders \
- producer/simple-producer--delivery-timeout \
- producer/spring-producer \
- producer/spring-producer--vorlage \
- producer/spring-producer--fixedsharding \
- producer/spring-producer--fixedsharding--vorlage \
- producer/spring-producer--delivery-timeout \
- producer/spring-producer--delivery-timeout--vorlage \
- producer/spring-producer--backpressure \
- producer/spring-producer--backpressure--vorlage \
- producer/spring-producer--auditheaders \
- producer/spring-producer--auditheaders--vorlage \
- producer/spring-producer--generics \
- producer/rest-producer \
- springkafka/spring-producer--livecoding \
- springkafka/spring-producer--livecoding--schritte \
- springkafka/spring-producer \
- springkafka/spring-producer--vorlage \
- springkafka/spring-producer--json \
- springkafka/spring-producer--json--vorlage \
- springkafka/spring-producer--json--messages \
- springkafka/spring-producer--json--messages--vorlage \
- springkafka/spring-producer--messageconverter \
- springkafka/spring-producer--kafkatemplate \
- springkafka/spring-producer--kafkatemplate--vorlage \
- springkafka/technik-check \
- springkafka/supersimple-producer \
- springkafka/supersimple-producer--vorlage \
- grundlagen/simple-consumer \
- grundlagen/simple-consumer--vorlage \
- grundlagen/simple-consumer--livecoding \
- grundlagen/simple-consumer--livecoding--schritte \
- grundlagen/simple-consumer--image--vorlage \
- consumer/simple-consumer--megagroup--vorlage \
- consumer/simple-consumer--max-poll-interval-ms \
- consumer/simple-consumer--retention-ms--vorlage \
- consumer/spring-consumer--livecoding \
- consumer/spring-consumer--livecoding--schritte \
- consumer/spring-consumer \
- consumer/spring-consumer--vorlage \
- consumer/nodlt \
- consumer/spring-consumer--logic-error \
- consumer/spring-consumer--logic-error--vorlage \
- consumer/spring-consumer--long \
- consumer/spring-consumer--deserialization-error \
- consumer/spring-consumer--deserialization-error--vorlage \
- consumer/spring-consumer--seek \
- consumer/spring-consumer--seek--vorlage \
- consumer/spring-consumer--assign \
- consumer/spring-consumer--assign--vorlage \
- consumer/spring-consumer--rebalance-listener \
- consumer/spring-consumer--rebalance-listener--vorlage \
- consumer/spring-consumer--log-compaction \
- consumer/spring-consumer--generics \
- consumer/spring-consumer--record-handler \
- consumer/spring-consumer--health-indicator \
- consumer/spring-consumer--error-handling \
- springkafka/spring-consumer--vorlage \
- springkafka/spring-consumer--json \
- springkafka/spring-consumer--json--vorlage \
- springkafka/sumup-messages--vorlage \
- springkafka/spring-consumer--json--messages \
- springkafka/spring-consumer--json--messages--vorlage \
- springkafka/spring-consumer--kafkahandler \
- springkafka/spring-consumer--messageconverter \
- springkafka/spring-consumer--messageconverter--dlt \
- springkafka/supersimple-consumer \
- springkafka/supersimple-consumer--vorlage \
- springkafka/spring-consumer--kafkalistener \
- springkafka/spring-consumer--kafkalistener--concurrency \
- springkafka/spring-consumer--kafkalistener--logic-error \
- springkafka/spring-consumer--kafkalistener--long \
- springkafka/spring-consumer--kafkalistener--long--deserialization-error \
- springkafka/spring-consumer--kafkalistener--long--dlt \
- springkafka/spring-producer--long \
- springkafka/spring-producer--long--vorlage \
- "
#!/bin/bash
-# Gemeinsame Hilfsfunktionen für alle Verwaltungsskripte.
-# Bindet branches.sh ein und stellt $BRANCH_NAMES sowie Hilfsfunktionen bereit.
+# Gemeinsame Daten und Hilfsfunktionen für alle Verwaltungsskripte.
+# Enthält $BRANCHES, $BRANCH_ROOT und $BRANCH_NAMES sowie Hilfsfunktionen.
-source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/branches.sh"
+BRANCHES="\
+ grundlagen/docker \
+ producer/batch-size--vorlage \
+ grundlagen/simple-producer \
+ grundlagen/simple-producer--vorlage \
+ grundlagen/simple-producer--livecoding \
+ grundlagen/simple-producer--livecoding--schritte \
+ grundlagen/simple-producer--image--vorlage \
+ grundlagen/simple-producer--fire+forget--vorlage \
+ grundlagen/simple-producer--completablefuture \
+ producer/simple-producer--auditheaders \
+ producer/simple-producer--delivery-timeout \
+ producer/spring-producer \
+ producer/spring-producer--vorlage \
+ producer/spring-producer--fixedsharding \
+ producer/spring-producer--fixedsharding--vorlage \
+ producer/spring-producer--delivery-timeout \
+ producer/spring-producer--delivery-timeout--vorlage \
+ producer/spring-producer--backpressure \
+ producer/spring-producer--backpressure--vorlage \
+ producer/spring-producer--auditheaders \
+ producer/spring-producer--auditheaders--vorlage \
+ producer/spring-producer--generics \
+ producer/rest-producer \
+ springkafka/spring-producer--livecoding \
+ springkafka/spring-producer--livecoding--schritte \
+ springkafka/spring-producer \
+ springkafka/spring-producer--vorlage \
+ springkafka/spring-producer--json \
+ springkafka/spring-producer--json--vorlage \
+ springkafka/spring-producer--json--messages \
+ springkafka/spring-producer--json--messages--vorlage \
+ springkafka/spring-producer--messageconverter \
+ springkafka/spring-producer--kafkatemplate \
+ springkafka/spring-producer--kafkatemplate--vorlage \
+ springkafka/technik-check \
+ springkafka/supersimple-producer \
+ springkafka/supersimple-producer--vorlage \
+ grundlagen/simple-consumer \
+ grundlagen/simple-consumer--vorlage \
+ grundlagen/simple-consumer--livecoding \
+ grundlagen/simple-consumer--livecoding--schritte \
+ grundlagen/simple-consumer--image--vorlage \
+ consumer/simple-consumer--megagroup--vorlage \
+ consumer/simple-consumer--max-poll-interval-ms \
+ consumer/simple-consumer--retention-ms--vorlage \
+ consumer/spring-consumer--livecoding \
+ consumer/spring-consumer--livecoding--schritte \
+ consumer/spring-consumer \
+ consumer/spring-consumer--vorlage \
+ consumer/nodlt \
+ consumer/spring-consumer--logic-error \
+ consumer/spring-consumer--logic-error--vorlage \
+ consumer/spring-consumer--long \
+ consumer/spring-consumer--deserialization-error \
+ consumer/spring-consumer--deserialization-error--vorlage \
+ consumer/spring-consumer--seek \
+ consumer/spring-consumer--seek--vorlage \
+ consumer/spring-consumer--assign \
+ consumer/spring-consumer--assign--vorlage \
+ consumer/spring-consumer--rebalance-listener \
+ consumer/spring-consumer--rebalance-listener--vorlage \
+ consumer/spring-consumer--log-compaction \
+ consumer/spring-consumer--generics \
+ consumer/spring-consumer--record-handler \
+ consumer/spring-consumer--health-indicator \
+ consumer/spring-consumer--error-handling \
+ springkafka/spring-consumer--vorlage \
+ springkafka/spring-consumer--json \
+ springkafka/spring-consumer--json--vorlage \
+ springkafka/sumup-messages--vorlage \
+ springkafka/spring-consumer--json--messages \
+ springkafka/spring-consumer--json--messages--vorlage \
+ springkafka/spring-consumer--kafkahandler \
+ springkafka/spring-consumer--messageconverter \
+ springkafka/spring-consumer--messageconverter--dlt \
+ springkafka/supersimple-consumer \
+ springkafka/supersimple-consumer--vorlage \
+ springkafka/spring-consumer--kafkalistener \
+ springkafka/spring-consumer--kafkalistener--concurrency \
+ springkafka/spring-consumer--kafkalistener--logic-error \
+ springkafka/spring-consumer--kafkalistener--long \
+ springkafka/spring-consumer--kafkalistener--long--deserialization-error \
+ springkafka/spring-consumer--kafkalistener--long--dlt \
+ springkafka/spring-producer--long \
+ springkafka/spring-producer--long--vorlage \
+ "
+
+# Rebase-Elternbeziehungen: BRANCH_ROOT[branch]=root
+# Maßgebliche Quelle: ROOT-Tabelle in CLAUDE.md — diese Map ist die maschinenlesbare Entsprechung.
+# grundlagen/docker ist Wurzel-Branch (ROOT = sich selbst) und wird von rebase.sh übersprungen.
+declare -A BRANCH_ROOT=(
+ ["grundlagen/docker"]="grundlagen/docker"
+ ["producer/batch-size--vorlage"]="grundlagen/docker"
+ ["grundlagen/simple-producer"]="grundlagen/docker"
+ ["grundlagen/simple-producer--vorlage"]="grundlagen/simple-producer"
+ ["grundlagen/simple-producer--livecoding"]="grundlagen/simple-producer"
+ ["grundlagen/simple-producer--livecoding--schritte"]="grundlagen/simple-producer--livecoding"
+ ["grundlagen/simple-producer--image--vorlage"]="grundlagen/simple-producer"
+ ["grundlagen/simple-producer--fire+forget--vorlage"]="grundlagen/simple-producer--image--vorlage"
+ ["grundlagen/simple-producer--completablefuture"]="grundlagen/simple-producer"
+ ["producer/simple-producer--auditheaders"]="grundlagen/simple-producer"
+ ["producer/simple-producer--delivery-timeout"]="grundlagen/simple-producer"
+ ["producer/spring-producer"]="grundlagen/simple-producer"
+ ["producer/spring-producer--vorlage"]="producer/spring-producer"
+ ["producer/spring-producer--fixedsharding"]="producer/spring-producer"
+ ["producer/spring-producer--fixedsharding--vorlage"]="producer/spring-producer--fixedsharding"
+ ["producer/spring-producer--delivery-timeout"]="producer/spring-producer"
+ ["producer/spring-producer--delivery-timeout--vorlage"]="producer/spring-producer--delivery-timeout"
+ ["producer/spring-producer--backpressure"]="producer/spring-producer--delivery-timeout"
+ ["producer/spring-producer--backpressure--vorlage"]="producer/spring-producer--backpressure"
+ ["producer/spring-producer--auditheaders"]="producer/spring-producer--backpressure"
+ ["producer/spring-producer--auditheaders--vorlage"]="producer/spring-producer--auditheaders"
+ ["producer/spring-producer--generics"]="producer/spring-producer"
+ ["producer/rest-producer"]="producer/spring-producer"
+ ["springkafka/spring-producer--livecoding"]="producer/spring-producer"
+ ["springkafka/spring-producer--livecoding--schritte"]="springkafka/spring-producer--livecoding"
+ ["springkafka/spring-producer"]="producer/spring-producer"
+ ["springkafka/spring-producer--vorlage"]="springkafka/spring-producer"
+ ["springkafka/spring-producer--json"]="springkafka/spring-producer"
+ ["springkafka/spring-producer--json--vorlage"]="springkafka/spring-producer--json"
+ ["springkafka/spring-producer--json--messages"]="springkafka/spring-producer--json"
+ ["springkafka/spring-producer--json--messages--vorlage"]="springkafka/spring-producer--json--messages"
+ ["springkafka/spring-producer--messageconverter"]="springkafka/spring-producer--json"
+ ["springkafka/spring-producer--kafkatemplate"]="springkafka/spring-producer"
+ ["springkafka/spring-producer--kafkatemplate--vorlage"]="springkafka/spring-producer--kafkatemplate"
+ ["springkafka/technik-check"]="springkafka/spring-producer--kafkatemplate"
+ ["springkafka/supersimple-producer"]="producer/spring-producer"
+ ["springkafka/supersimple-producer--vorlage"]="springkafka/supersimple-producer"
+ ["grundlagen/simple-consumer"]="grundlagen/simple-producer"
+ ["grundlagen/simple-consumer--vorlage"]="grundlagen/simple-consumer"
+ ["grundlagen/simple-consumer--livecoding"]="grundlagen/simple-consumer"
+ ["grundlagen/simple-consumer--livecoding--schritte"]="grundlagen/simple-consumer--livecoding"
+ ["grundlagen/simple-consumer--image--vorlage"]="grundlagen/simple-consumer"
+ ["consumer/simple-consumer--megagroup--vorlage"]="grundlagen/simple-consumer"
+ ["consumer/simple-consumer--max-poll-interval-ms"]="grundlagen/simple-consumer"
+ ["consumer/simple-consumer--retention-ms--vorlage"]="grundlagen/simple-consumer"
+ ["consumer/spring-consumer--livecoding"]="grundlagen/simple-consumer"
+ ["consumer/spring-consumer--livecoding--schritte"]="consumer/spring-consumer--livecoding"
+ ["consumer/spring-consumer"]="grundlagen/simple-consumer"
+ ["consumer/spring-consumer--vorlage"]="consumer/spring-consumer"
+ ["consumer/nodlt"]="consumer/spring-consumer"
+ ["consumer/spring-consumer--logic-error"]="consumer/spring-consumer"
+ ["consumer/spring-consumer--logic-error--vorlage"]="consumer/spring-consumer--logic-error"
+ ["consumer/spring-consumer--long"]="consumer/spring-consumer"
+ ["consumer/spring-consumer--deserialization-error"]="consumer/spring-consumer--long"
+ ["consumer/spring-consumer--deserialization-error--vorlage"]="consumer/spring-consumer--deserialization-error"
+ ["consumer/spring-consumer--seek"]="consumer/spring-consumer"
+ ["consumer/spring-consumer--seek--vorlage"]="consumer/spring-consumer--seek"
+ ["consumer/spring-consumer--assign"]="consumer/spring-consumer"
+ ["consumer/spring-consumer--assign--vorlage"]="consumer/spring-consumer--assign"
+ ["consumer/spring-consumer--rebalance-listener"]="consumer/spring-consumer"
+ ["consumer/spring-consumer--rebalance-listener--vorlage"]="consumer/spring-consumer--rebalance-listener"
+ ["consumer/spring-consumer--log-compaction"]="consumer/spring-consumer--rebalance-listener"
+ ["consumer/spring-consumer--generics"]="consumer/spring-consumer"
+ ["consumer/spring-consumer--record-handler"]="consumer/spring-consumer--generics"
+ ["consumer/spring-consumer--health-indicator"]="consumer/spring-consumer--record-handler"
+ ["consumer/spring-consumer--error-handling"]="consumer/spring-consumer--record-handler"
+ ["springkafka/spring-consumer--vorlage"]="consumer/spring-consumer"
+ ["springkafka/spring-consumer--json"]="consumer/spring-consumer"
+ ["springkafka/spring-consumer--json--vorlage"]="springkafka/spring-consumer--json"
+ ["springkafka/sumup-messages--vorlage"]="springkafka/spring-consumer--json"
+ ["springkafka/spring-consumer--json--messages"]="springkafka/spring-consumer--json"
+ ["springkafka/spring-consumer--json--messages--vorlage"]="springkafka/spring-consumer--json--messages"
+ ["springkafka/spring-consumer--kafkahandler"]="springkafka/spring-consumer--json"
+ ["springkafka/spring-consumer--messageconverter"]="springkafka/spring-consumer--kafkahandler"
+ ["springkafka/spring-consumer--messageconverter--dlt"]="springkafka/spring-consumer--messageconverter"
+ ["springkafka/supersimple-consumer"]="consumer/spring-consumer"
+ ["springkafka/supersimple-consumer--vorlage"]="springkafka/supersimple-consumer"
+ ["springkafka/spring-consumer--kafkalistener"]="consumer/spring-consumer"
+ ["springkafka/spring-consumer--kafkalistener--concurrency"]="springkafka/spring-consumer--kafkalistener"
+ ["springkafka/spring-consumer--kafkalistener--logic-error"]="springkafka/spring-consumer--kafkalistener"
+ ["springkafka/spring-consumer--kafkalistener--long"]="springkafka/spring-consumer--kafkalistener"
+ ["springkafka/spring-consumer--kafkalistener--long--deserialization-error"]="springkafka/spring-consumer--kafkalistener--long"
+ ["springkafka/spring-consumer--kafkalistener--long--dlt"]="springkafka/spring-consumer--kafkalistener--long--deserialization-error"
+ ["springkafka/spring-producer--long"]="springkafka/spring-producer"
+ ["springkafka/spring-producer--long--vorlage"]="springkafka/spring-producer--long"
+)
# Array aller Branch-Namen als Strings
BRANCH_NAMES=($BRANCHES)