Files changed: - CHANGES.md - VERSION - tools/CONTRACT.md - tools/chemenu/commands/git_publish.py - tools/chemenu/tests/test_git_publish.py
This commit is contained in:
+52
@@ -35,6 +35,58 @@ dev-checkout concern - readable here, never shipped as something to parse.
|
||||
|
||||
---
|
||||
|
||||
## 5.0.1-beta.1 - 2026-09-12 - publish: ungeborene main ist kein detached HEAD, erster Push zu leerem Remote (schliesst #96, #97)
|
||||
|
||||
**Author:** Torben Nehmer
|
||||
|
||||
<!-- wikitool:bumps -->
|
||||
- publish: ungeborene main ist kein detached HEAD, erster Push zu leerem Remote (schliesst #96, #97)
|
||||
<!-- /wikitool:bumps -->
|
||||
|
||||
Zwei Defekte, die zusammen dazu führten, dass eine frisch aufgesetzte Instanz
|
||||
sich über keinen dokumentierten Weg initial veröffentlichen ließ. Beide sitzen
|
||||
in `publish` und wurden erst beim Einrichten einer 5.0.0-Instanz aus dem
|
||||
Release-Tarball sichtbar - der Pfad, den `instructions/setup-instance.md`
|
||||
Schritt 14 als *den* ersten schreibenden Aufruf einer neuen Instanz nennt.
|
||||
|
||||
**Ein ungeborener Branch ist kein detached HEAD.** `current_branch()` fragte
|
||||
`git rev-parse --abbrev-ref HEAD`. Nach `git init -b main`, vor dem ersten
|
||||
Commit, zeigt `HEAD` auf einen Ref, der sich nicht auflöst: `rev-parse` endet
|
||||
mit Exit 128 und war damit von einem echten detached HEAD nicht zu
|
||||
unterscheiden. Der erste `publish` einer neuen Instanz brach deshalb mit
|
||||
"Refusing to push `main` from a detached HEAD" ab, und Invariante 5 schneidet
|
||||
den naheliegenden Ausweg (`git commit` von Hand) ab. Die Funktion liest jetzt
|
||||
`git symbolic-ref --short -q HEAD` - was `HEAD` *benennt* statt worauf es
|
||||
zeigt. Damit beantwortet die Branch-Prüfung den ungeborenen Fall korrekt,
|
||||
statt für ihn ausgesetzt werden zu müssen: sie vergleicht `main` mit `main`
|
||||
und lässt durch. Ein echter detached HEAD wird unverändert abgelehnt, und ein
|
||||
`--branch`, das nicht dem ausgecheckten entspricht, ebenfalls.
|
||||
|
||||
**Ein nie gepushter Branch ist nicht "nicht ahead".** `_local_ahead_of_remote()`
|
||||
entscheidet, ob ein sauberer Working-Tree trotzdem etwas zu pushen hat, und
|
||||
gab `False` zurück, sobald kein Tracking-Ref existierte. Genau das ist der Fall
|
||||
bei einem frisch angelegten, leeren Remote-Repository: der lokale Commit stand,
|
||||
`publish` meldete "Nothing to commit" und pushte nie - beliebig oft
|
||||
wiederholbar. Unterschieden wird jetzt über `git ls-remote --exit-code`, dessen
|
||||
Exit-Code die drei Lagen ohne Textvergleich trennt (0 = Ref vorhanden,
|
||||
2 = Remote erreichbar und ohne diesen Ref, 128 = unerreichbar oder gar nicht
|
||||
konfiguriert); auf die Meldung zu matchen schiede aus, weil git sie übersetzt.
|
||||
Nur der mittlere Fall gilt als "ahead", und auch dort nur, wenn lokal
|
||||
überhaupt ein Commit existiert. Ein unerreichbares Remote behält bewusst das
|
||||
bisherige Verhalten, damit Offline- und Nur-lokal-Instanzen keine
|
||||
Verhaltensänderung sehen. `remote_ref_exists()` bleibt unangetastet - sein
|
||||
zweiter Aufrufer `reconcile()` meint damit weiterhin richtig "nichts zum
|
||||
Abgleichen da".
|
||||
|
||||
`tools/CONTRACT.md` zieht beides nach: die `publish`-Zeile beschrieb den
|
||||
Strandungsfall bisher als gelöst, was für einen nie gepushten Branch nicht
|
||||
stimmte, und der Fehlerkontrakt benennt die Branch-Prüfung jetzt als
|
||||
eigenständigen Exit-1-Grund. `instructions/setup-instance.md` und `INSTALL.md`
|
||||
blieben inhaltlich richtig - sie hatten den Umweg nie beschrieben, sondern den
|
||||
Weg, der jetzt tatsächlich funktioniert.
|
||||
|
||||
---
|
||||
|
||||
## 5.0.0 - 2026-09-11 - TOC-Pflicht in docs verify, Konfidenz-Mechanismus ersatzlos entfernt
|
||||
|
||||
**Author:** Torben Nehmer
|
||||
|
||||
Reference in New Issue
Block a user