Repository-Regeln (.gitcito.json)
Jedes Projekt trägt Regeln mit sich, die sich aus dem Code nicht ableiten
lassen. Niemals direkt auf release/* pushen. Commit-Scopes sind api, web
und infra, sonst nichts. Du brauchst Node 20, ausgecheckte Submodule und eine
.env, kopiert aus .env.example, bevor irgendetwas läuft. Solche Regeln
stehen in einer README, die niemand erneut liest, in einem CI-Fehler, oder im
Kopf der Person, die am längsten dabei ist.
.gitcito.json ist der Ort, an dem ein Repository sie aufschreibt, damit das
Werkzeug danach handeln kann. Die Datei liegt im Repository-Wurzelverzeichnis,
wird wie jede andere Datei versioniert und reist damit mit dem Klon: alle, die
das Projekt öffnen, bekommen dieselben Regeln — und neue Mitarbeitende bekommen
sie am ersten Tag statt beim ersten abgelehnten Push.
Die Datei ist völlig optional. Ein Repository ohne sie verhält sich genau wie bisher.
Sie müssen sie nicht von Hand schreiben: Der Repository-Chat kennt das Schema dieser Datei, also kommt füge Ticket-Links für JIRA-1234 hinzu oder schütze die Release-Branches als prüfbare Dateiaktion zurück.

Wo man sie bearbeitet
Das Zahnrad neben den Werkzeugen der Symbolleiste → Config. Dieser Editor schreibt die Datei in deinen Arbeitsbaum; sie wird sonst nirgends gespeichert — also committe sie, um die Regeln mit dem Team zu teilen.
Hat das Repository noch keine, schlägt Repository lesen eine aus dem vor, was
ohnehin schon da ist: eine .nvmrc oder engines.node, eine .gitmodules,
filter=lfs in .gitattributes, eine .env.example ohne .env daneben, die
Branches, die du lokal schon schützt, und die Scopes, die die letzten 500
Commit-Betreffs verwendet haben. Nichts wird geschrieben, bis du speicherst. Im
Terminal macht gitcito config init dasselbe (siehe
die Kommandozeile).
Was die Datei sagen kann
{
"version": 1,
"protect": ["main", "release/*"],
"links": {
"tickets": [
{ "match": "\\b[A-Z][A-Z0-9]+-\\d+\\b", "url": "https://tracker.example.com/browse/$0", "label": "Jira" }
]
},
"commit": {
"scopes": ["api", "web", "infra"],
"ticketFromBranch": true,
"trailers": ["Refs: {ticket}"]
},
"requires": {
"node": ">=20",
"hooksPath": ".husky",
"submodules": true,
"lfs": true,
"files": [{ "path": ".env", "from": ".env.example", "why": "API-Basis-URL und ein Dev-Token" }]
},
"checklist": {
"push": ["Die Integrationssuite gegen Staging laufen lassen"]
}
}
| Feld | Was es tut |
|---|---|
version |
Muss 1 sein. Eine Datei aus einem neueren Schema wird ganz ignoriert, statt geraten zu werden. |
protect |
Branch-Namen, * passt auf beliebigen Text. Wird zu den lokal geschützten Branches hinzugefügt — siehe geschützte Branches. |
links.tickets |
Ein regulärer Ausdruck und eine URL-Vorlage. $0 ist der ganze Treffer, $1…$9 seine Gruppen. Treffer in Commit-Betreff und -Text werden zu Links. |
commit.scopes |
Die Scopes, die der Composer anbietet, statt eines Freitextfelds. Sie zu deklarieren macht aus einem unbekannten Scope in gitcito commit-check außerdem einen Fehler statt eines Stilhinweises. |
commit.ticketFromBranch |
Füllt den Ticket-Schlüssel aus dem Branch-Namen (feature/ABC-123-sache → ABC-123) — aber nur in einen leeren Composer, nie über etwas, das du gerade tippst. |
commit.trailers |
Zeilen, die an den Commit-Text angehängt werden. {ticket} und {branch} werden gefüllt; eine Zeile, deren Platzhalter nichts zu füllen hat, wird verworfen statt halb geschrieben. |
requires.* |
Was ein funktionierender Klon braucht. Jeder Eintrag wird zu einer Doctor-Zeile, siehe unten. |
checklist.push |
Freitext, einmal pro Sitzung vor dem ersten Push angezeigt. |
Der Doctor
requires ist der Teil, der „ich habe es geklont und es läuft nicht"
beantwortet. Gitcito prüft es beim Öffnen des Repositorys und zeigt einen
Stethoskop-Chip in der Statusleiste, wenn etwas nicht stimmt. Ein Klick öffnet
den Config-Tab bei den Doctor-Zeilen; Erneut prüfen führt sie noch einmal
aus.
| Prüfung | Besteht, wenn | Reparatur |
|---|---|---|
node |
Das node in deinem PATH erfüllt die Angabe |
— |
submodules |
Kein Submodul ist ohne Checkout | git submodule update --init --recursive |
lfs |
git-lfs ist installiert und die getrackten Dateien sind echte Inhalte, kein Pointer-Text | git lfs pull |
hooksPath |
core.hooksPath entspricht dem deklarierten Pfad |
core.hooksPath setzen |
files |
Die Datei existiert | sie aus from kopieren, falls vorhanden |
Zwei bewusste Grenzen. Eine Warnung bedeutet nie „kaputt" — sie bedeutet, dass
der Doctor etwas nicht bestimmen konnte (eine unlesbare Node-Angabe besteht,
statt einen Fehler zu erfinden, gegen den du nichts tun kannst), und Warnungen
lassen gitcito doctor in der CI nicht fehlschlagen. Und eine Reparatur ist nie
etwas, das die Datei geliefert hat: die Menge oben ist die ganze Menge, zur
Compile-Zeit geschlossen. Die Konfiguration gibt ihr einen Wert — einen Pfad zum
Kopieren, einen Wert für core.hooksPath — und nie einen Befehl.
Das Kopieren überschreibt nie: dass die Datei fehlt, ist genau der Grund, warum die Zeile da ist.
Commits
Sind commit.scopes deklariert, bietet die Scope-Schaltfläche des Composers
diese Liste statt eines Freitextfelds — der Unterschied zwischen feat(renderer)
und feat(rendererr). ticketFromBranch und trailers füllen die mechanischen
Teile einer Nachricht, und links.tickets macht aus den Schlüsseln überall dort
wieder Links, wo ein Commit angezeigt wird.
Dieselben Regeln gelten außerhalb des Fensters: gitcito commit-check liest
diese Datei, sodass ein commit-msg-Hook und die CI genau das durchsetzen, was
der Composer vorschlägt. Siehe die Kommandozeile und
Committen.
Die Push-Checkliste
checklist.push erscheint als Bestätigung vor dem ersten Push einer Sitzung,
eine Zeile je Eintrag. Sie ist der Platz für das, was wirklich Ermessenssache ist
— hat jemand dem Support Bescheid gesagt? —, denn Gitcito prüft das nie für
dich. Es sind Erinnerungen, keine Sperren: lesen und pushen, oder abbrechen.
Einmal pro Repository und Sitzung, denn ein Dialog bei jedem Push ist ein Dialog,
den niemand liest.
Warum sie dir nicht schaden kann
Die Datei kommt mit dem Repository — also von wem auch immer das Repository geschrieben hat. Sie wird als nicht vertrauenswürdiger Inhalt behandelt, genau wie eine Commit-Nachricht:
- Nichts darin wird ausgeführt. Es gibt kein Feld, das einen Befehl enthält, und die Reparaturen des Doctors sind eine feste Liste.
- Sie kann nur Einschränkungen hinzufügen.
protectist die Vereinigung mit deiner lokalen Liste — ein Repository kann mehr schützen, als du gewählt hast, dir aber nie einen Schutz ausreden. Kein Feld schaltet eine Sicherung ab. - Pfade können das Repository nicht verlassen. Absolute Pfade,
..,~, Laufwerksbuchstaben und alles, was.gitberührt, werden abgelehnt — und dort erneut geprüft, wo aus einer Zeichenkette ein echter Pfad wird. - Links müssen
http(s)sein. Nichts anderes wird dem URL-Öffner des Systems übergeben. - Alles ist gedeckelt — Listenlängen, Textlängen, Musterlängen —, damit ein feindliches Repository keine Textwand in einen Dialog und keine tausend Chips in ein Panel kippen kann.
Ein fehlerhaftes Feld wird verworfen, nicht fatal. Der Rest der Datei gilt
weiterhin, und das Verworfene steht mit Begründung unter Von Gitcito
ignoriert im Config-Tab. Die einzige Ausnahme ist ungültiges JSON oder eine
unbekannte version — da gibt es nichts zu retten.
Was sie bewusst nicht tut
- Keine Befehle, keine Skripte, keine Hooks. Dafür gibt es Hooks, und die sind eine Entscheidung pro Klon.
- Keine Regeln pro Branch oder pro Person. Eine Datei, ein Regelsatz.
- Sie ersetzt die CI nicht. Die Checkliste ist Text; der Doctor prüft die Umgebung, nicht deine Arbeit.
- Sie kann nichts abschwächen. Jede Sicherung von Gitcito bleibt deine.
Siehe auch: Einstellungen pro Repository · Die Kommandozeile · Committen · Hooks & .gitignore