Git Commit-Template: einheitliche Commit-Nachrichten im Team erzwingen
AI generated
git
HEAD
Git · Team-Workflow
Commit-Templates im Team
Einheitliche Commit-Nachrichten erzwingen

Ein Commit-Template gibt vor, wie eine Commit-Nachricht aufgebaut sein soll, doch ohne technische Durchsetzung bleibt es eine Empfehlung, die im Alltag schnell ignoriert wird. Dieser Artikel zeigt, wie aus einer einfachen .gitmessage Datei ein Regelwerk wird, das lokal, im Hook und in der CI tatsächlich greift.

10 Min. Lesezeit Git Team-Workflow Commit-Konventionen

1. Warum uneinheitliche Commit-Nachrichten teuer werden

Eine Commit-Historie ist im besten Fall eine lesbare Chronik, die erklärt, warum eine Änderung stattgefunden hat, nicht nur was geändert wurde. In der Praxis sieht die Historie vieler Repositories aber anders aus: Nachrichten wie fix, update oder wip tauchen im Wechsel mit ausführlichen Absätzen auf, ohne erkennbares Muster. Wer später mit git log oder git blame nach dem Grund einer Änderung sucht, findet in solchen Repositories oft nichts Brauchbares, obwohl die Information technisch vorhanden wäre, nur eben nicht strukturiert.

Das Problem verschärft sich mit der Teamgröße, weil jeder Entwickler seinen eigenen Stil mitbringt und ohne Vorgabe auch behält. Ein Reviewer kann eine unklare Nachricht zwar im Pull Request bemängeln, aber das kostet Zeit und führt selten zu einer dauerhaften Verhaltensänderung, weil die Korrektur immer erst nachträglich erfolgt. Ein Commit-Template setzt genau hier an, indem es die Struktur bereits im Editor vorgibt, bevor der Commit überhaupt erstellt wird, und damit die Wahrscheinlichkeit einer sinnvollen Nachricht deutlich erhöht.

2. Grundlagen: commit.template und .gitmessage

Git erlaubt es, per Konfiguration eine Textdatei zu hinterlegen, die beim Aufruf von git commit ohne -m als Vorlage im Editor erscheint. Die Konfigurationsoption heißt commit.template und verweist auf eine beliebige Datei, üblicherweise .gitmessage im Home-Verzeichnis oder im Repository selbst. Alles, was in dieser Datei mit einer Raute beginnt, wird als Kommentar behandelt und beim Speichern automatisch aus der endgültigen Nachricht entfernt, sodass sich die Vorlage frei mit Hinweisen und Beispielen füllen lässt, ohne die eigentliche Nachricht zu verunreinigen.

Für ein einzelnes Repository reicht eine lokale git config Einstellung, für ein ganzes Team ist es sinnvoller, die Vorlage als Datei im Repository zu versionieren und die Konfiguration über ein Setup-Skript oder direkt in der README zu dokumentieren. So sieht jeder neue Mitarbeiter dieselbe Vorlage, ohne sie manuell abtippen zu müssen.


# Vorlage im Repository ablegen
cat > .gitmessage <<'EOF'
# <typ>(<bereich>): <kurze Zusammenfassung, max. 50 Zeichen>
#
# Ausführlichere Beschreibung des Warum, nicht nur des Was.
# Zeilenumbruch bei etwa 72 Zeichen.
#
# Bezugnehmende Ticket-Nummer oder Issue-Referenz, z.B. Refs: JIRA-123
EOF

# Konfiguration für dieses Repository
git config commit.template .gitmessage

# Konfiguration global für alle Repositories eines Entwicklers
git config --global commit.template ~/.gitmessage

3. Aufbau einer guten Template-Datei

Eine bewährte Struktur orientiert sich an den Conventional Commits, weil das Format nicht nur für Menschen lesbar ist, sondern sich auch maschinell auswerten lässt, etwa für automatisch generierte Changelogs. Der Aufbau besteht aus einem Typ wie feat, fix, docs oder refactor, einem optionalen Bereich in Klammern und einer kurzen Zusammenfassung im Imperativ, gefolgt von einer Leerzeile und einem ausführlicheren Body.

Wichtig ist, dass die Vorlage konkrete Beispiele enthält statt nur abstrakter Platzhalter, weil Entwickler unter Zeitdruck eher eine Vorlage kopieren und anpassen, als eine Regel aus dem Gedächtnis zu rekonstruieren. Ebenso hilfreich ist ein Hinweis auf die maximale Zeilenlänge der ersten Zeile, weil viele Tools, darunter GitHub und GitLab, die erste Zeile in Listenansichten abschneiden und eine zu lange Zusammenfassung dort unleserlich wird.

4. Lokale Einrichtung vs. teamweite Verteilung

Eine rein lokale Vorlage, die jeder Entwickler manuell einrichtet, funktioniert nur so lange, wie niemand vergisst, sie einzurichten, und genau das passiert in der Praxis regelmäßig bei neuen Teammitgliedern oder frisch geklonten Maschinen. Zuverlässiger ist es, die Vorlage und die Konfiguration Teil eines Onboarding-Skripts zu machen, das ohnehin beim ersten Setup ausgeführt wird, etwa zusammen mit der Installation von Abhängigkeiten oder Git-Hooks.

Da commit.template selbst nicht versioniert werden kann, weil es sich um eine lokale Konfigurationsoption handelt, bleibt die Vorlage nur eine Empfehlung, solange sie nicht technisch erzwungen wird. Der nächste Schritt ist deshalb immer eine serverseitige oder CI-basierte Prüfung, die unabhängig von der lokalen Einrichtung greift.


#!/usr/bin/env bash
# scripts/setup-git.sh, Teil des Onboarding-Prozesses
set -euo pipefail

git config commit.template .gitmessage
git config core.hooksPath .githooks

echo "Git Commit-Template und Hooks eingerichtet."

5. Durchsetzung mit dem lokalen commit-msg Hook

Ein commit-msg Hook erhält den Pfad zur temporären Datei mit der eingegebenen Commit-Nachricht als Argument und kann den Commit-Vorgang mit einem Fehlercode abbrechen, bevor er überhaupt entsteht. Damit lässt sich technisch prüfen, ob eine Nachricht dem geforderten Format entspricht, etwa per regulärem Ausdruck gegen das Conventional-Commits-Schema.

Der Hook liegt im Verzeichnis .git/hooks, das nicht versioniert wird, weshalb er entweder über core.hooksPath auf ein versioniertes Verzeichnis umgeleitet oder über ein Tool wie Husky installiert werden muss. Wichtig ist, dass der Hook nur lokal greift und von jedem Entwickler mit --no-verify umgangen werden kann, weshalb er allein keine verlässliche Durchsetzung darstellt, sondern nur schnelles Feedback direkt beim Committen liefert.


#!/usr/bin/env bash
# .githooks/commit-msg
MSG_FILE="$1"
PATTERN='^(feat|fix|docs|style|refactor|perf|test|chore)(\([a-z0-9_-]+\))?: .{1,50}'

if ! grep -qE "$PATTERN" "$MSG_FILE"; then
  echo "Commit-Nachricht entspricht nicht dem geforderten Format." >&2
  echo "Beispiel: feat(checkout): Gutschein-Validierung ergänzen" >&2
  exit 1
fi

6. Verbindliche Durchsetzung mit commitlint in der CI

Weil lokale Hooks umgangen werden können, gehört die eigentliche Durchsetzung in die CI-Pipeline, wo sie nicht mehr optional ist. Das Tool commitlint prüft Commit-Nachrichten gegen ein konfigurierbares Regelwerk und wird üblicherweise mit der Preset-Konfiguration für Conventional Commits betrieben. In der Pipeline reicht ein Job, der alle neuen Commits eines Merge Requests oder Pull Requests gegen das Regelwerk prüft und bei Verstoß fehlschlägt.

Diese Prüfung sollte so früh wie möglich in der Pipeline laufen, weil sie schnell ist und keine Abhängigkeiten zu Build oder Tests hat. Ein fehlgeschlagener commitlint-Job liefert dem Entwickler außerdem eine präzise Fehlermeldung mit dem verletzten Regel-Namen, was die Korrektur deutlich einfacher macht als eine generische Ablehnung im Review.


# commitlint.config.js
module.exports = { extends: ["@commitlint/config-conventional"] };

# In der CI Pipeline, z.B. GitLab CI oder GitHub Actions
npx commitlint --from=origin/main --to=HEAD --verbose

7. Interaktive Unterstützung mit Commitizen

Statt sich auf das Gedächtnis der Entwickler zu verlassen, kann ein interaktives Tool wie Commitizen die Nachricht Schritt für Schritt abfragen: Typ, Bereich, Zusammenfassung, ausführliche Beschreibung und Breaking-Change-Hinweise werden nacheinander erfragt und am Ende zu einer formkonformen Nachricht zusammengesetzt. Der Aufruf erfolgt über git cz statt git commit und produziert dadurch praktisch immer eine valide Nachricht, ohne dass der Entwickler das Format aktiv im Kopf behalten muss.

Der Vorteil gegenüber einer reinen Text-Vorlage liegt in der geführten Eingabe, die Tippfehler im Typ-Feld praktisch ausschließt, weil die Auswahl aus einer Liste erfolgt statt aus freier Texteingabe. In Kombination mit dem commit-msg Hook als Fallback für Entwickler, die weiterhin git commit direkt nutzen, lässt sich so eine hohe Formatkonsistenz erreichen, ohne jedem Workflow vorzuschreiben, welches Tool er benutzen muss.

8. Automatisiertes Changelog aus Commit-Nachrichten

Ein strukturiertes Commit-Format zahlt sich am deutlichsten aus, sobald daraus automatisch ein Changelog erzeugt wird. Tools wie conventional-changelog oder release-please lesen die Commit-Historie seit dem letzten Release, gruppieren die Einträge nach Typ und erzeugen daraus eine strukturierte Release-Notiz, ohne dass ein Mensch die Änderungen manuell zusammenfassen muss.

Diese Automatisierung funktioniert nur zuverlässig, wenn die zugrunde liegenden Commit-Nachrichten tatsächlich konsistent sind, weshalb sie einen zusätzlichen, sehr konkreten Anreiz für Teams liefert, die Durchsetzung ernst zu nehmen: Ein einzelner Commit ohne korrekten Typ fällt im Changelog entweder ganz heraus oder landet in einer unpassenden Kategorie, was schnell auffällt und die Motivation für saubere Nachrichten im Alltag erhöht.

9. Einführung in einem bestehenden Repository

Bei einem gewachsenen Repository lohnt es sich nicht, alte Commit-Nachrichten rückwirkend anzupassen, weil das die Historie über git rebase massiv verändern würde und für alle bestehenden Klone zu Konflikten führt. Stattdessen wird die neue Regelung ab einem festen Zeitpunkt eingeführt, üblicherweise ab dem nächsten Release-Tag, und der commitlint-Job in der CI prüft nur Commits, die nach diesem Zeitpunkt entstanden sind.

Ein sanfter Einstieg besteht darin, die CI-Prüfung zunächst nur als Warnung laufen zu lassen, bevor sie nach einer Übergangsphase von wenigen Wochen zum Pflicht-Check wird, der einen fehlgeschlagenen Merge Request tatsächlich blockiert. So gewöhnt sich das Team an das neue Format, bevor es verbindlich durchgesetzt wird, und die Akzeptanz im Team ist am Ende deutlich höher als bei einer sofortigen harten Einführung.

Ansatz Durchsetzungsgrad Umgehbar Feedback-Zeitpunkt
Nur .gitmessage Vorlage Empfehlung Ja, jederzeit Keines
commit-msg Hook lokal Mittel Ja, mit --no-verify Beim Commit
commitlint in der CI Hoch Nein, blockiert Merge Bei Push/MR
Commitizen (git cz) Mittel Ja, bei direktem git commit Beim Commit

Mironsoft

Git-Workflows, Branching-Strategien und CI-Hooks

Chaotische Git-Historie und unklare Branching-Regeln im Team?

Wir richten saubere Git-Workflows ein, klären Branching-Strategien fürs Team und automatisieren Qualitätschecks über Git-Hooks und CI-Pipelines, damit die Historie nachvollziehbar bleibt.

Workflow-Audit

Bestehende Branching-Strategie und Merge-Praxis auf Schwachstellen prüfen.

Hook-Automatisierung

Pre-Commit- und Pre-Push-Hooks für Linting, Tests und Commit-Konventionen einrichten.

Team-Schulung

Rebase, Cherry-Pick und Konfliktauflösung im Team praxisnah vermitteln.

10. Zusammenfassung

Commit-Templates

Lokale Vorlage

commit.template + .gitmessage Datei im Repository

Lokale Prüfung

commit-msg Hook, umgehbar mit --no-verify

Verbindliche Prüfung

commitlint als Pflicht-Job in der CI-Pipeline

Nutzen

Automatisch generierbares Changelog aus der Historie

11. FAQ: Commit-Templates

1Kann ich commit.template in Git versionieren?
Die Konfigurationsoption commit.template selbst liegt in der lokalen Git-Konfiguration und wird nicht mitversioniert. Die Vorlagendatei .gitmessage kann aber problemlos im Repository liegen, sodass jeder Entwickler nur noch git config commit.template .gitmessage einmalig ausführen muss.
2Reicht ein commit-msg Hook allein aus, um das Format durchzusetzen?
Nein. Ein lokaler Hook lässt sich mit dem Flag --no-verify umgehen, und Hooks im Verzeichnis .git/hooks werden beim Klonen ohnehin nicht mitgeliefert. Für eine verbindliche Durchsetzung ist immer zusätzlich eine Prüfung in der CI-Pipeline nötig.
3Was ist der Unterschied zwischen commit.template und einem Pull-Request-Template?
commit.template füllt den Text-Editor beim lokalen Ausführen von git commit vor, bevor überhaupt ein Commit entsteht. Ein Pull-Request-Template ist eine separate Vorlage der Hosting-Plattform, die erst beim Öffnen des Pull Requests erscheint und die Beschreibung der gesamten Änderung strukturiert, nicht einzelne Commits.
4Wie gehe ich mit Merge-Commits um, die commitlint nicht bestehen?
Die meisten commitlint-Konfigurationen ignorieren automatisch generierte Merge-Commits, weil deren Format von Git selbst vorgegeben wird und nicht dem Conventional-Commits-Schema folgt. Über die Option ignores lassen sich solche Ausnahmen explizit definieren, falls die Standardkonfiguration sie nicht bereits abdeckt.
5Muss jeder Commit dem strengen Format folgen, auch kleine Zwischen-Commits?
In der Praxis prüfen die meisten Teams nur die Commits, die tatsächlich in den Zielbranch gemergt werden, oft nach einem Squash oder Rebase. Zwischen-Commits während der Entwicklung auf einem Feature-Branch müssen dann nicht jeder einzeln dem Format entsprechen, solange der finale Merge-Commit oder Squash-Commit korrekt formatiert ist.
6Welche Commit-Typen sollte die Vorlage mindestens abdecken?
Ein bewährter Mindestsatz umfasst feat für neue Funktionen, fix für Fehlerbehebungen, docs für Dokumentation, refactor für Umbauten ohne Verhaltensänderung, test für Tests und chore für Wartungsarbeiten wie Abhängigkeits-Updates. Weitere Typen wie perf oder style lassen sich bei Bedarf ergänzen.
7Wie lässt sich das Commit-Format mit Jira- oder Ticket-Referenzen kombinieren?
Am einfachsten als zusätzliche Zeile im Footer der Commit-Nachricht, etwa Refs: PROJ-123 oder Closes: PROJ-123, getrennt durch eine Leerzeile vom Body. Die Vorlage kann diese Zeile bereits als auskommentierten Platzhalter enthalten, damit niemand das Format der Referenz falsch schreibt.
8Was passiert, wenn ein Entwickler die Vorlage einfach löscht und eine eigene Nachricht schreibt?
Solange kein technischer Check aktiv ist, kann jeder die Vorlage ignorieren oder überschreiben. Genau deshalb ersetzt die Vorlage keine Durchsetzung, sondern liefert nur die Struktur, während commitlint in der CI die eigentliche Kontrolle übernimmt.
9Lohnt sich Commitizen für ein kleines Team?
Bei zwei bis drei Entwicklern reicht oft schon eine gute Vorlage und Disziplin, weil der Abstimmungsaufwand gering ist. Sobald das Team wächst oder neue Mitglieder regelmäßig dazukommen, reduziert Commitizen die Einarbeitungszeit deutlich, weil das Tool das Format aktiv vorgibt statt es nur zu dokumentieren.
10Kann ich bestehende, unformatierte Commit-Nachrichten nachträglich korrigieren?
Technisch ja, über ein interaktives Rebase mit git rebase -i und reword für jeden betroffenen Commit, allerdings verändert das die Commit-Hashes und damit die Historie für alle, die das Repository bereits geklont haben. In geteilten Repositories lohnt sich das nur in Ausnahmefällen, meist ist ein Neustart ab einem Stichtag praktikabler.