# 0007 – Branchmodell: drei Kanäle, `stable` als stabiler Kanal, Rückführungspflicht Status: vorgeschlagen · Datum: 2026-09-04 · Beteiligte: AG QGIS ## Kontext Es gab eine erste Beschreibung des Git-Vorgehens (Wiki-Export „Git-Konzept"), die drei Branches `main`/`testing`/`unstable` beschrieb und den Branch-Schutz auf GitHub erklärte. Der Abgleich mit den Repositories am 04.09.2026 ergab vier Abweichungen: 1. **Ein stabiler Kanal-Branch existiert in keinem Plugin-Repository.** Vorhanden sind `unstable`, `testing` und in zwei Repos ein nicht mehr bespieltes `oldstable`. Der Skill `sn-release` vermerkt entsprechend „stable derzeit ohne Branch". 2. **Der Branchname ist nicht frei wählbar.** Der Release-Workflow in `Repository`, Branch `hidden/workflows` (Michael Otto, 19.06.2026), klont das Plugin-Repository und führt `git checkout "$CHANNEL"` aus. `$CHANNEL` wird im Workflow des Plugin-Repos (Michael Otto, 18.03.2026) aus dem Tag-Suffix abgeleitet und ist `unstable`, `testing` oder `stable`. **Der Branch muss also genauso heißen wie der Kanal.** Ein Branch `main` würde den stabilen Release-Pfad brechen. 3. Der Branch-Schutz wurde für GitHub beschrieben, wir arbeiten mit Gitea 1.27. 4. Branch-Namen sind uneinheitlich: `bug/crash_on_exit`, `feature/Drucklayout-überarbeiten` (Umlaut), `alkis-nur-laden-stop` und `fix-fbschl-feldname` (ohne Präfix). Zusätzlich fehlte die Antwort auf die praktisch wichtigste Frage: Wo fängt ein Fix an, der einen Release-Kandidaten in `testing` betrifft? ## Entscheidung Die Kette lautet `feature/*` → `unstable` → `testing` → `stable`. Der stabile Kanal heißt **`stable`** und wird angelegt; er entspricht dem Feed `plugins.xml` und dem Tag ohne Suffix. `oldstable` wird als Altlast archiviert. `stable` statt `main`, weil die vorhandene Release-Infrastruktur den Branchnamen aus dem Kanalnamen ableitet. `main` wäre möglich, würde aber eine Änderung an fremder, funktionierender Infrastruktur samt Testrelease erfordern — ohne fachlichen Gewinn. Der Name ist im Projekt ohnehin durchgängig verankert: `CHANNEL`-Variable, Tag-Logik, `plugins.xml`. **Der Einstiegspunkt eines Fixes richtet sich nach dem Kanal, in dem der Fehler auftritt**, nicht nach seiner Dringlichkeit. Ein Fix an `testing` oder `stable` ist erst abgeschlossen, wenn er per Pull Request in alle darunterliegenden Kanäle zurückgeführt wurde. Ohne Rückführung verschwindet der Fix beim nächsten Hochstufen. Branch-Namen: `feature/`, `bugfix/`, `hotfix/`, `doku/`, `release/`, jeweils mit Issue-Nummer, ASCII, klein, Bindestriche. Die drei Kanäle sind auf Gitea gegen direkten Push geschützt. **Push, Merge und Tag bleiben bei Menschen.** KI-Agenten bereiten vor; die entsprechenden Kommandos sind in `.claude/settings.json` technisch gesperrt, damit die Regel nicht nur auf Zuruf gilt. Vollständige Fassung: `docs/leitfaden/05_git_arbeitsweise.md`. ## Folgen Der Maintainer muss `stable` je Plugin-Repository anlegen und die Schutzregeln setzen (`docs/konzept/08_repo_einrichten.md`). Bis dahin endet die Kette bei `testing` und der stabile Feed bleibt leer. Jeder Fix an `testing` kostet einen zweiten Pull Request — das ist gewollt und billiger als ein wiederauftauchender Fehler. Vier verwaiste Branches im Bestand sind zu prüfen und zu löschen. Wer den Branch später doch `main` nennen will, muss zuerst `git checkout "$CHANNEL"` in `Repository:hidden/workflows` um eine Kanal→Branch-Zuordnung erweitern und das mit einem Testrelease auf `Plugin_Test_Action` absichern. Diese Entscheidung wäre dann zu ersetzen. ## Verworfene Alternativen Den stabilen Kanal `main` nennen (vertraute Git-Konvention, bricht aber den Release-Workflow, solange die Infrastruktur nicht mit angepasst wird — Eingriff in fremde, funktionierende Automatisierung ohne fachlichen Gewinn); bei zwei Kanälen bleiben (dann gibt es dauerhaft kein produktionsreifes Ziel und `plugins.xml` bleibt leer); Fixes grundsätzlich in `unstable` beginnen und nach `testing` vorziehen (Cherry-Picks über mehrere Kanäle sind fehleranfälliger als der umgekehrte Weg).