Initialisiere die Ablage in place statt zu klonen

SilverBullet mountet dasselbe Volume und legt seine Dateien an, bevor km
dran ist — der clone scheiterte auf hive.home an einem nicht leeren
Verzeichnis. Jetzt: init im Verzeichnis, Remote holen, Branch auschecken
wenn vorhanden, sonst legt der erste Push ihn an. Die Eigendateien der
Oberfläche (.silverbullet*, _plug/) kommen in die .gitignore der Ablage.
Dazu die restlichen Umlaute im compose-Kommentar.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 18:49:17 +02:00
co-authored by Claude Fable 5.1
parent 996d82b26f
commit 0770ff06f0
2 changed files with 29 additions and 24 deletions
+6 -6
View File
@@ -2,9 +2,9 @@
#
# Zwei Container auf einem Volume:
# km API + Takt: zieht die Ablage, liest Gitea ein, indexiert
# (SQLite FTS5 + sqlite-vec), liefert alles Geaenderte ein
# silverbullet Oberflaeche auf demselben Verzeichnis -- lesen und aendern;
# km committet und pusht die Aenderungen im naechsten Takt
# (SQLite FTS5 + sqlite-vec), liefert alles Geänderte ein
# silverbullet Oberfläche auf demselben Verzeichnis -- lesen und ändern;
# km committet und pusht die Änderungen im nächsten Takt
#
# Die Wahrheit ist das Git-Remote (KM_GIT_REMOTE); /srv/km/data/ablage ist
# ein Checkout, /srv/km/data/km-index.sqlite ein Cache. Beides ist ohne die
@@ -13,9 +13,9 @@
# Secrets stehen in `.env` daneben (root-only) und NICHT hier:
# KM_GIT_USER / KM_GIT_PASSWORD Push an das Ablage-Repo
# KM_GITEA_USER / KM_GITEA_PASSWORD Lesen der Forge
# SB_USER user:passwort fuer die Oberflaeche
# SB_USER user:passwort für die Oberfläche
#
# Betrieb ueber `oci` (42i-oci): /srv/km/compose.yml, `oci enable km`.
# Betrieb über `oci` (42i-oci): /srv/km/compose.yml, `oci enable km`.
services:
km:
@@ -57,7 +57,7 @@ services:
SB_FOLDER: /space
SB_PORT: "3000"
# hive.home teilt den Pfadraum an der Wurzel (hive/core#61); die
# Oberflaeche liegt deshalb unter /km, die API unter /km/api.
# Oberfläche liegt deshalb unter /km, die API unter /km/api.
SB_URL_PREFIX: /km
SB_USER: ${SB_USER}
# die Dateien gehören dem km-Container (root); ohne PUID rät
+23 -18
View File
@@ -54,25 +54,30 @@ class Ablage:
def ensure(self) -> None:
"""Checkout vorhanden machen: klonen, sonst init -- nie stillschweigend leer."""
a = self.cfg.ablage
if (a / ".git").exists():
return
a.parent.mkdir(parents=True, exist_ok=True)
if self.cfg.git_remote:
r = subprocess.run(["git", "clone", "--branch", self.cfg.git_branch, self.cfg.git_remote, str(a)],
capture_output=True, text=True)
if r.returncode != 0:
# leeres Remote: Branch gibt es noch nicht -> init und ersten Push
if "Remote branch" in r.stderr or "not found" in r.stderr or "warning: You appear" in r.stderr:
a.mkdir(parents=True, exist_ok=True)
self._git("init", "-b", self.cfg.git_branch)
self._git("remote", "add", "origin", self.cfg.git_remote)
else:
raise SystemExit(f"km: clone fehlgeschlagen: {r.stderr.strip()}")
else:
if not (a / ".git").exists():
# Kein clone: das Verzeichnis existiert oft schon, weil SilverBullet
# dasselbe Volume mountet und dort seine Dateien anlegt, bevor km
# dran ist. Also in place initialisieren und den Remote-Stand holen.
a.mkdir(parents=True, exist_ok=True)
self._git("init", "-b", self.cfg.git_branch)
self._git("config", "user.name", self.cfg.git_name)
self._git("config", "user.email", self.cfg.git_email)
self._git("init", "-q", "-b", self.cfg.git_branch)
if self.cfg.git_remote:
self._git("remote", "add", "origin", self.cfg.git_remote)
r = self._git("fetch", "-q", "origin", check=False)
if r.returncode != 0:
raise SystemExit(f"km: fetch von {self.cfg.git_remote} fehlgeschlagen: {r.stderr.strip()[:300]}")
has_branch = self._git("rev-parse", "--verify", "-q", f"origin/{self.cfg.git_branch}", check=False).returncode == 0
if has_branch:
r = self._git("checkout", "-q", "-B", self.cfg.git_branch, f"origin/{self.cfg.git_branch}", check=False)
if r.returncode != 0:
raise SystemExit(f"km: checkout kollidiert mit vorhandenen Dateien: {r.stderr.strip()[:300]}")
# sonst: leeres Remote, der erste Push legt den Branch an
self._git("config", "user.name", self.cfg.git_name)
self._git("config", "user.email", self.cfg.git_email)
# Was die Oberflaeche fuer sich selbst ablegt, gehoert nicht in die Wahrheit.
gi = a / ".gitignore"
wanted = ".silverbullet*\n_plug/\n"
if not gi.exists() or wanted not in gi.read_text():
gi.write_text((gi.read_text() if gi.exists() else "") + wanted)
def pull(self) -> None:
if not self.cfg.git_remote: