Arbeitsablauf
Führe diese Schritte der Reihe nach aus. Stoppe und melde dem Benutzer, wenn ein Schritt fehlschlägt.
1. Arbeitsverzeichnis prüfen
Führe git status und git diff (sowohl gestaged als auch ungestaged) aus, um zu verstehen, was sich geändert hat. Wenn es überhaupt keine Änderungen gibt, teile dem Benutzer mit, dass es nichts zu committen gibt, und stoppe.
2. Verschmutzte Submodule bereinigen
Wenn git status Submodule mit "(modified content)" anzeigt, aber keine gestageten oder beabsichtigten Submodule-Zeigeränderungen vorliegen, handelt es sich um verschachtelte Sub-Submodule, die abgewichen sind (typischerweise durch ein rekursives --remote-Update). Führe für jedes solche verschmutzte Submodule git -C <submodule-pfad> submodule update --init aus, um die verschachtelten Referenzen auf die vom übergeordneten Submodule erwarteten Commits wiederherzustellen. Überprüfe nach der Bereinigung erneut mit git status, dass der Schmutz verschwunden ist. Stagte KEINE Submodule-Zeigeränderungen, es sei denn, der Benutzer hat sie explizit geändert.
3. Alles stagen, es sei denn, der Benutzer hat etwas anderes angegeben
Wenn der Benutzer keine bestimmten Dateien angegeben hat, stage alle Änderungen (verfolgte und unverfolgte) mit git add -A. Wenn der Benutzer bestimmte Dateien oder Pfade genannt hat, stage nur diese.
4. Linting und automatische Korrektur
Vor dem Commit erkenne den Linter des Projekts und führe ihn mit automatischer Korrektur für die gestageten Dateien aus. Erkennungsreihenfolge:
- Projektweites Lint-Ziel zuerst: Wenn das Makefile ein
lint- oderlint:fix-Ziel hat, oder package.json einlint- oderlint:fix-Skript, bevorzuge dieses – es respektiert die eigenen Konventionen des Projekts. Fahre mit der sprachspezifischen Erkennung nur fort, wenn kein projektweites Ziel existiert. - Go (go.mod vorhanden): führe
gofmt -wauf gestageten .go-Dateien aus, danngo vet ./... - JavaScript/TypeScript (package.json vorhanden): führe
npx eslint --fixauf gestageten JS/TS-Dateien aus, wenn eine ESLint-Konfiguration existiert. Wenn Prettier konfiguriert ist, führe auchnpx prettier --writeauf diesen Dateien aus. - Python (pyproject.toml, setup.py oder requirements.txt vorhanden): führe
ruff check --fixundruff formatauf gestageten .py-Dateien aus, wenn Ruff konfiguriert ist. Falle zurück aufblack, falls installiert. Falle zurück aufflake8(nur Bericht, keine automatische Korrektur). - Rust (Cargo.toml vorhanden): führe
cargo fmtundcargo clippy --fix --allow-dirtyaus. - Kein Linter erkannt: überspringe diesen Schritt und fahre fort.
Nach der automatischen Korrektur stagte alle geänderten Dateien erneut mit git add -u. Wenn der Linter Fehler meldet, die nicht automatisch korrigiert werden konnten, stoppe und melde sie dem Benutzer – committe nicht mit bekannten Lint-Fehlern.
Wenn ein Linter erkannt wird, aber das Binary nicht installiert ist, warne den Benutzer und frage, ob ohne Linting fortgefahren oder abgebrochen werden soll.
5. Commit-Nachricht generieren
Analysiere den gestageten Diff, um eine Conventional-Commit-Nachricht zu erzeugen:
type(scope): Kurzzusammenfassung
Optionaler Body mit Kontext, was geändert wurde und warum.
Regeln:
- type: einer von feat, fix, refactor, docs, test, chore, ci, perf, style, build
- scope: optional, aber bevorzugt – leite ihn vom primären Package, Modul oder Verzeichnis ab, das berührt wurde. Lasse ihn nur weg, wenn die Änderungen zu viele Bereiche umfassen, als dass ein einzelner Scope sinnvoll wäre.
- Zusammenfassungszeile: Kleinbuchstaben, Imperativ, kein Punkt, maximal 72 Zeichen.
- Body: füge ihn nur hinzu, wenn der Diff nicht trivial ist und die Zusammenfassung allein einem Reviewer nicht genügend Kontext geben würde. Halte ihn prägnant.
- Mehrere logische Änderungen: wähle die dominierende für type/scope aus, erwähne sekundäre Änderungen im Body. Teile NICHT in mehrere Commits auf, es sei denn, der Benutzer bittet explizit darum.
- Breaking Changes: füge einen BREAKING CHANGE-Footer hinzu oder verwende das !-Suffix (z. B. feat!: ...).
- Wenn der Linter Dateien automatisch korrigiert hat, erwähne dies im Body (z. B. "Enthält gofmt-Auto-Korrekturen.").
6. Commit
Führe git commit mit der generierten Nachricht aus. Verwende -m für reine Zusammenfassungsnachrichten. Für Nachrichten mit einem Body schreibe in eine temporäre Datei und verwende git commit -F, um Zeilenumbrüche zu erhalten, und bereinige dann die temporäre Datei.
7. Mit Remote synchronisieren
Ermittle den aktuellen Branch-Namen. Dann:
- Wenn der Branch einen Upstream hat, führe
git pushaus. - Wenn der Branch keinen Upstream hat, führe
git push -u origin <branch-name>aus. - Wenn der Push abgelehnt wird, weil das Remote voraus ist, führe
git pull --rebaseund dann erneutpushaus. Wenn der Rebase zu Konflikten führt, stoppe und melde – löse Merge-Konflikte nicht automatisch auf.
8. Bestätigung
Melde dem Benutzer:
- Commit-Hash (Kurzform)
- Verwendete Commit-Nachricht
- Branch-Name und Remote-Synchronisierungsstatus
- Geänderte Dateien, Einfügungen, Löschungen (aus
git diff --statdes Commits) - Welcher Linter ausgeführt wurde (oder dass keiner erkannt wurde)
Randfälle
- Kein Remote konfiguriert: committe lokal und informiere den Benutzer.
- Detached HEAD: warne vor dem Commit, schlage vor, zuerst einen Branch zu erstellen.
- Nur unverfolgte Dateien: stage und committe sie normal.
- Respektiere .gitignore – füge ignorierte Dateien niemals mit
git add -fhinzu, es sei denn, der Benutzer bittet explizit darum.