Vorlage:Commit messages
Inhaltsverzeichnis
- 1 Was sind gute Commit Messages und warum man diese erstellen sollte.
- 1.1 Aufbau einer Commit Message
- 1.2 Tipps für Gute Commits
- 1.2.1 Ein Commit sollte nie die Buildfähigkeit brechen!
- 1.2.2 Du bist nichts besonderes!
- 1.2.3 Mache einfache Commits!
- 1.2.4 Sei spezifisch und genau! Hilf es einfach zu finden!
- 1.2.5 Erkläre, was Du gemacht hast, erkläre, warum Du es genau so implementiert hast!
- 1.2.6 Teile Auffälligkeiten und Besonderheiten mit!
- 1.2.7 Unterlasse unnötige Interjektion
- 1.2.8 Stelle keine anderen Mitglieder bloß!
- 1.3 Kommunikation
- 2 Wann comitten?
- 3 Script zum Erstellen einer ChangeLog
Was sind gute Commit Messages und warum man diese erstellen sollte.
Commit Messages sind ein wichtiger Bestandteil der Kommunikation und Information in einem Projekt und sollten nicht als lästiges Beiwerk betrachtet werden. Sie dienen dazu, den anderen Beteiligten und Interessenten mitzuteilen, was in einem Commit geändert wurde und warum es geändert wurde. Um sicherzustellen, dass diese Informationen effizient und elektronisch verwertbar sind (z.B. zur Erstellung einer ChangeLog-Datei), sollten bestimmte Regeln beachtet werden.
Eine aussagekräftige Commit Message erspart anderen Beteiligten eine aufwendige Suche und erhöht die Effektivität des Teams. Sie bildet auch die Grundlage für eine gezielte Suche zu einem späteren Zeitpunkt, insbesondere bei der Fehlersuche, die in der Regel auf Basis der Commit Messages erfolgt.
Das Schreiben einer aussagekräftigen Commit Message erfordert normalerweise nur wenige Minuten Zeit. Diese Investition kann sich jedoch später durch eine erhebliche Zeitersparnis beim Durchsuchen der History oder des Sourcecodes bemerkbar machen, sodass der Entwickler sich auf seine eigentliche Tätigkeit, das Programmieren, konzentrieren kann. Wenn Du bisher noch nicht in dieser Weise gearbeitet hast, lies bitte die folgenden Hinweise und überlege, ob es nicht besser wäre, es zumindest auszuprobieren.
Aufbau einer Commit Message
- Die erste Zeile Deines Commits sollte immer aus einer kurzen Zusammenfassung bestehen, die aus Zahlen und Buchstaben besteht und keine Anführungszeichen oder ähnliches enthält.
- Diese erste Zeile sollte nicht mehr als 50 Zeichen umfassen, und übliche Editoren helfen dabei, dies einzuhalten, indem sie die Zeichenfarbe ändern.
- Danksagungen für Zuarbeit oder ähnliches sollten nicht in der ersten Zeile enthalten sein!
- Commit-IDs (egal ob Kurzform oder Langform) haben in der ersten Zeile ebenfalls nichts zu suchen. Wenn es notwendig ist, verweise bitte im erläuternden Teil der Commit-Message auf einen anderen Commit.
- Hintergrund: Commit-IDs zeigen nur auf Commits der Historie, in welcher sie erzeugt wurden. Sobald man Commits in andere Branches übernimmt und auf verschiedene Branches rebased oder von einem anderen Branch pickt, ändern sich die IDs und werden mit ziemlicher Sicherheit ungültig. Wenn man auf einen Commit verweisen möchte, sollte man daher immer möglichst nur den Reintext der ersten Zeile des Commits als Verweis nehmen.
- Es ist gute Praxis, die Funktion, logische Einheit oder auch eine Bugnummer gefolgt von einem Doppelpunkt der kurzen Zusammenfassung voranzustellen.
- Bei Revert-Commits ist es wichtig, eine klare Erklärung zu liefern, warum ein vorheriger Commit zurückgenommen wurde. Dadurch wird anderen Entwicklern und Interessierten ermöglicht, die Gründe für die Rücknahme zu verstehen.
Wenn Du noch mehr zu sagen hast (was fast immer der Fall ist), beachte Folgendes:
- Die zweite Zeile bleibt prinzipiell leer!
- Ab der dritten Zeile beginnt Deine ausführlichere Darstellung des Commits. Auch hier sollte jede Zeile nicht länger als 72 Zeichen sein, und für die Strukturierung der Punkte kannst Du diverse Anführungszeichen wie
*, -, #
verwenden. Schreibe Deine Nachricht in der gegenwartsbezogenen Verlaufsform!
Ein Beispiel aus der Linuxkernelentwicklung. [1]
loop: export module parameters Export 'max_loop' and 'max_part' parameters to sysfs so user can know that how many devices are allowed and how many partitions are supported. If 'max_loop' is 0, there is no restriction on the number of loop devices. User can create/use the devices as many as minor numbers available. If 'max_part' is 0, it means simply the device doesn't support partitioning. Also note that 'max_part' can be adjusted to power of 2 minus 1 form if needed. User should check this value after the module loading if he/she want to use that number correctly (i.e. fdisk, mknod, etc.).
Im Vi bzw. VIM lässt sich die maximale Textbreite mit
set textwidth=72
schnell und einfach auf 72 Zeichen setzen! Ein Eintrag dieser Anweisung in die ~/.vimrc
veranlasst Vi bzw. VIM bei jedem Start diese Textbreite zu benutzen. Siehe auch Beispiel einer .vimrc
Tipps für Gute Commits
Die Qualität der Commit-Nachrichten spielt eine wichtige Rolle. Eine unzureichende Beschreibung kann den Eindruck erwecken, dass das Repository schlampig gepflegt wird. Selbst wenn es sich Deiner Ansicht nach um ein privates Projekt handelt, sollte man bedenken, dass die Historie öffentlich zugänglich ist und Interesse wecken kann. Insbesondere wenn man ein Repository bei renommierten Hostern betreibt, auf denen sich auch Softwareanbieter aus der ganzen Welt tummeln. Wenn man nicht gewissenhaft damit umgeht, sollte man in Erwägung ziehen, das Repository lieber nicht öffentlich zu betreiben.
Ein Commit sollte nie die Buildfähigkeit brechen!
Ein Commit sollte niemals die Funktionalität des Projekts beeinträchtigen, daher gilt dies als goldene Regel. Jeder, der an dem Projekt arbeitet, sollte in der Lage sein, es auch mit deinem Commit weiterzubauen. Vergewissere dich also immer, dass deine Arbeit möglichst fehlerfrei ist, bevor du sie committest. Es macht keinen guten Eindruck, wenn auffällig häufig Commits zurückgenommen werden müssen.
Du bist nichts besonderes!
Jeder glaubt, dass er gute Commit-Nachrichten schreiben kann, und in den meisten Fällen ist dies auch der Fall. Aber nach einer gewissen Zeit kann jeder, auch Du, nachlässig werden! Wenn Du denkst, dass Deine Commits außergewöhnlich sind, solltest Du kritisch über die letzten 100 Commits nachdenken und überlegen, wie viele davon wirklich außergewöhnlich sind. Mach es einfach mal aus Spaß und überprüfe es selbst.
Mache einfache Commits!
Dies kann wortwörtlich genommen werden: Selbst komplexe Aufgaben sollten in der Regel in einzelnen Commits erledigt werden. Jeder Commit sollte vorzugsweise ein spezifisches Problem lösen, eine neue Funktion hinzufügen oder Änderungen an einer bestimmten Datei vornehmen. Ein Commit sollte eine logische Einheit bilden, die später bei Bedarf einzeln zurückgenommen werden kann, ohne dass andere Commits betroffen sind. Dies ist besonders wichtig, wenn man automatisierte Fehlersuche mit git bisect
betreibt oder wenn man Commit-Nachrichten erstellt. Finde das richtige Gleichgewicht!
Sei spezifisch und genau! Hilf es einfach zu finden!
Folgende Message hat sicherlich jeder schon gesehen oder gar selber verfasst, die schlechteste aller möglichen Messages!
fixed some bugs
Wow, wer hätte das gedacht!
fix foo id
Na toll, und was war da damit jetzt? Muss ich jetzt den Code durchforsten?
fix
Der Klassiker!
Beim Verfassen der Commit-Message sollte der Autor berücksichtigen, dass die Umstände, Gründe und Lösungen für das behandelte Problem für andere möglicherweise nicht sofort ersichtlich sind. Daher ist es ratsam, eine kurze Beschreibung des Problems und der Lösung bereitzustellen, um die Nachvollziehbarkeit und Verständlichkeit der Commits zu erhöhen. Auch wenn es zunächst ein gewisser Aufwand ist, kann dies später viel Zeit und Mühe sparen. Insbesondere wenn man bedenkt, dass manche Commits erst Jahre später überprüft oder geändert werden müssen.
Grundsätzlich ist es niemandes Absicht, Bugs einzubauen. Daher sollte Dein Commit darauf abzielen, vorhandene Fehler zu beseitigen. Wenn Du eine größere Anzahl von Fehlern gefunden und behoben hast, solltest Du dies auch in Deiner Commit-Message vermerken und erklären, warum Du dies getan hast. Später wirst auch Du möglicherweise nach etwas suchen, über das Du nur noch vage beschei weißt, und genau dann wird eine erfolgreiche Suche in den Commit-Messages von Vorteil sein. Schreibe daher eine Commit-Message im Satz, die das Warum zumindest andeutet, wie zum Beispiel:
Fixed bad allocations in image processing routines.
Wie bereits erwähnt, erleichtern thematische Markierungen das Finden von Commits erheblich. Es empfiehlt sich, den Commit generisch einzuleiten und z.B. den Namen eines Features, eines Moduls (Funktion), eines Branches, Make-Targets, einer Implementierung o.ä. anzugeben. Ein gutes Beispiel hierfür findet sich in der Linux-Kernelentwicklung.
modulX: Fixed bad allocations in image processing routines
oder um es auf einen bestimmten Vorgang einzugrenzen:
clean up: removed unused variables.
So kann es bei komplexen Änderungen hilfreich sein, in der Commit-Message detaillierter zu beschreiben, welche Schritte unternommen wurden, um das Problem zu lösen oder die Funktionalität zu verbessern. Hierbei sollte man jedoch nicht ins Detail verfallen, sondern die Informationen prägnant und verständlich vermitteln. Dies hilft anderen Entwicklern, die Änderung besser zu verstehen und mögliche Auswirkungen auf andere Teile des Codes zu erkennen.
Sehr nützlich kann es sein, wenn man z.B. lokal viel in Branches arbeitet und hier naturgemäß kleinere Commits macht, diese mit dem Branchnamen markiert.
Branch_cleanups modulX: removed unused variables in ...
So fällt es leichter, die Commits auch noch ohne großes darauf schauen, einem Branch zuzuordnen. Wenn der Branchname auch noch ein Thema darstellt, kann man sogar nach einem Merge in den Master-Branch Rückschlüsse auf die Herkunft ziehen, ohne die Historie genauer zu studieren.
Es wird so schnell klar, sich hierbei Gedanken um etwas Organisation zu machen. Das ist noch nicht mal viel Aufwand. Man ist zumindest sich selbst dankbar und froh darüber, ohne großen Aufwand, irgendwann mal einen Commit zu finden, der genau zu einem Problem oder Vorgang passt. Schaue Dir andere Commits an, vergleiche diese mit Deinen.
Erkläre, was Du gemacht hast, erkläre, warum Du es genau so implementiert hast!
Dass Du am Code etwas programmiert, oder was auch immer Du am Code gemacht hast, kann jeder sehen und lesen, deshalb ist es generell ok dies anzumerken, aber erkläre, warum Du die Funktionalität genau so angepasst oder implementiert hast.
Teile Auffälligkeiten und Besonderheiten mit!
Du hast etwas schönes Neues für Dein Projekt, aber da es noch so neu ist und Du nicht alle Varianten prüfen konntest oder wolltest dann teile dies mit!
Adding a special GUI Option for the new entry XY
Dies beschreibt zwar Deine Arbeit, dies aber auch nur halb. Besser ist es zu mindestens noch mitzuteilen was funktioniert und wo es noch Probleme geben könnte.
Tested a seperate GUI entry, it works for the common way, but the function() for coloring may not working for the old models
Unterlasse unnötige Interjektion
Solche Messages sind völlig unbrauchbar und eher peinlich, oder was will uns diese Nachricht sagen? Und welchen Eindruck hinterlässt so eine Message in einem automatisch generiertem Changelog, wenn das ein interessierter User oder Kollege liest.
Messages, die im Eifer des Gefechts entstehen sind sicher kein Problem, solange aus der Message ersichtlich ist, warum man so formuliert, schliesslich kann man sich immer mal vertun und einen fehlerhaften Commit übermitteln und schnell korrigieren, aber ein ergänzender Hinweis wäre hier sicher nicht zu viel verlangt.
Stelle keine anderen Mitglieder bloß!
Solche Ansagen braucht keiner:
Fixed up heavy wrong typo, created by Beginner. Keep crap like that out of the code base.
Es ist wichtig, sachlich und konstruktiv zu bleiben, auch wenn man fehlerhaften Code gefunden hat. Anstatt beleidigender oder abfälliger Kommentare, sollte man sich auf das Problem konzentrieren und eine hilfreiche Lösung anbieten. Also lieber an die eigene Nase fassen, Schreibenergie besser in die eigenen Commit-Nachrichten stecken und Diskussionen auf Plattformen wie GitHub oder Stack Overflow sollten bevorzugt werden. Wir alle haben einmal klein angefangen, deshalb ist es wichtig, respektvoll und unterstützend zu bleiben. Eine bessere Commit-Nachricht könnte lauten:
Fixed wrong typo in function() that come with Revision XYZ
Kommunikation
In gewissen Situationen ist es wichtig, dass die Mitwirkenden eines Projekts in gegenseitigem Austausch stehen, um kontroverse Ansichten zu diskutieren und sicherzustellen, dass unpassende Änderungen vermieden werden. Eine erfolgreiche Zusammenarbeit erfordert dabei Kommunikations- und Kompromissbereitschaft, da nicht jeder Beteiligte über das gleiche Knowhow und den gleichen Zeitrahmen verfügt. Wenn die Kommunikation ins Stocken gerät, kann es passieren, dass manche Teilnehmer ungeduldig werden und sich entscheiden, ihr eigenes Ding zu machen, entweder spontan oder langfristig geplant. Allerdings ist es eine schlechte Idee, dies durch eine Kontaktverweigerung oder ein Ghosting zu tun, da dies den Unmut der übrigen Beteiligten hervorrufen kann und langfristig niemandem hilft.
In Zeiten von Git, spielen Unterprojekte (Forks) eine gewisse Rolle, was bestimmte Vor- und Nachteile mit sich bringt. Je nach Seriosität und Wartungsgrad solcher Projekte, kann das eine wertvolle Bereicherung sein, aber gerade hier kann sich die benannte Kontaktverweigerung mit Ansage negativ auswirken und den Sinn des Ganzen kaputt machen. Man sollte daher den Zugewinn an Möglichkeiten, sich auszutauschen, nicht verspielen.
In der heutigen Zeit, in der Git weit verbreitet ist, sind Unterprojekte (Forks) ein wichtiger Aspekt bei der Zusammenarbeit an Projekten. Allerdings bringen sie auch Vor- und Nachteile mit sich. Je nachdem wie seriös und wie gut gewartet solche Projekte sind, können sie eine wertvolle Ergänzung darstellen. Doch gerade in diesem Zusammenhang kann eine bewusste Kontaktverweigerung negativ auf die Zusammenarbeit auswirken und den Nutzen des Projekts mindern. Deshalb ist es wichtig, die Vorteile der Zusammenarbeit zu nutzen und nicht zu riskieren, diese durch solches Verhalten zu verlieren.
Kommunikation gegenüber Nutzern spielt sich insofern ab, als Ideen und deren schnelle Umsetzung gefordert werden, jedoch gibt es dafür oft verschiedene Lösungsansätze. In der Regel sind Nutzer oft daran interessiert, Wünsche schnell umgesetzt zu bekommen. Nutzer sehen aber oft nicht die sachlichen bzw. technischen Hintergründe. Bei gewünschten Übernahmen von Features ist es leider nicht immer mit einem einfachen Cherry-Pick aus verwandten Fork-Projekten getan, wenn dort schwer durchschaubare, unsaubere oder schlampige "Commit-Kultur" herrscht. Man sollte und kann daher nicht um jeden Preis allen Requests aus der Community bedingungslos nachkommen, nur weil dort ein nettes Feature drin ist, welches man auch gerne hätte. Übereifrige Übernahmen könnten thematische Überschneidungen in den Projekten von Kollegen verursachen und evtl. bessere Lösungsansätze kaputt machen, was zum Teil frustrierende Auswirkungen haben kann. Ständiges durchforschen, weil mal wieder nicht klar ist, was diese oder jene Änderung für Hintergründe hatte, weil nicht ersichtlich wird, ob diese Funktionen fehlerfrei, Nachbesserungen geplant oder nötig sind, tun ihr Übriges und sind nur einige Negativ-Beispiele. Brauchbare Lösungen und Konzepte lassen sich daher nur effektiv über Kommunikationswege vermitteln, auch hier sollte man die Wirksamkeit schlüssiger Commit-Nachrichten über Projektgrenzen hinaus nicht unterschätzen. Auch für zukünftige Dokumentationen sind diese Mitteilungen nachhaltige Informationsquellen und oft kann sich Kommunikation als Erstes um einen Commit entwickeln. Generell sind Commits mit aussagekräftigen Mitteilungen die erste Schnittstelle für Kommunikation und das sogar projektübergreifend. Commitmessages sollte man daher erst recht nicht vernachlässigen.
Langfristig gesehen, kann sich ein Projekt auch nur weiter entwickeln, wenn alles möglichst ausgewogen ineinander greift. Sollte man den Sinn einer Open-Source Gemeinschaft falsch verstanden haben oder der Meinung sein, sich unbedingt aus der Community hervorzutun, indem man versucht einem Projekt seinen ganz eigenen Stempel aufzudrücken, kann dies über kurz oder lang dazu führen, dass bestimmte Features, die nicht essenziell notwendig sind, gezielt gemieden werden und kein Austausch mehr erfolgt, was im Endeffekt zur völligen Inkompatibilität führen kann.
Wann comitten?
Lokal ist es ratsam seine Entwicklungsschritte abgetrennt in einem Branch und in einzelne Commits zu packen auch wenn diese zu einer Gesamtaufgabe gehören sollten. So kann man hier und da flexibel reverten oder weitere Branches ableiten, um Tests zu machen und wieder auf seinen Branch rebasen. Je nach dem wie man dann damit zufrieden ist, oder man der Meinung ist, das Ganze ist stimmig, kann man seine Commits zusammenfassen (Sichwort: git rebase -i) und als Patchsammlung verschicken bzw. als Entwickler auf den Entwicklungsbranch rebasen und ins Remote-Repo pushen.
Für Entwickler und überhaupt ist es durchaus ratsam nicht jeden anfallenden lokalen Commit druckfrisch in ein Remote-Repo zu schicken. Vorabtest sind durchaus angebracht. Gut "abgehangene" Commits, lassen sich lokal oft noch korrigieren und sinnvollerweise auf den Stand eines Remote-Repos rebasen und somit linear halten, denn oft findet man schon noch diesen oder jenen Bock, den man lieber vorher noch korrigieren sollte. Also sammeln ist insofern keine schlechte Idee.
Script zum Erstellen einer ChangeLog
Wenn man die Punkte von oben beachtet kann man mit diesem kleinen Script relativ schnell eine ChangLog Datei erstellen. Das Script ist recht rudimentär und ist sicherlich ausbaufähig und z.B. nur den ChangeLog zwischen zwei Commits oder Tags zu produzieren.
#!/bin/sh
# changelog.sh
# Convert git log to GNU-style ChangeLog file.
# (C) Chris
if test -d ".git"; then
git log --date-order --date=short | \
sed -e '/^commit.*$/d' | \
awk '/^Author/ {sub(/\\$/,""); getline t; print $0 t; next}; 1' | \
sed -e 's/^Author: //g' | \
sed -e 's/>Date: \([0-9]*-[0-9]*-[0-9]*\)/>\t\1/g' | \
# sed -e ‘s/\(.*\)>Date: \([0-9]*-[0-9]*-[0-9]*\)/\2 \1>/g’ | \
sed -e 's/^\(.*\) \(\)\t\(.*\)/\3 \1 \2/g' > ChangeLog
exit 0
else
echo "No git repository present."
exit 1
fi
Das ergibt dann einen solchen Output:
8< --- Carsten Schoenert <c.schoenert_at_t-online_dot_de> 2011-07-10 openvpn: fixing wrong position of patch call in the target ups, a poor copy paste error :-( And one forgotten warning! You should't use your STB as a VPN Gateway from/to the Internet! Every process on the box is running the root previleges, so if someone has taken your box he will full access to your local lan! Stefan Seyfried <seife_at_tuxbox-git_dot_slipkontur_dot_de> 2011-07-09 improve nfsd init script to check exports syntax Stefan Seyfried <seife_at_tuxbox-git_dot_slipkontur_dot_de> 2011-07-09 glibc-pkg: add libnsl to package (needed by samba) Carsten Schoenert <c.schoenert_at_t-online_dot_de> 2011-07-10 openvpn: new target for *the* open source VPN software In the between times some people from the dark side there some quicker than I and make a usable make target for openvpn. I made some little modification for using it in my buildsystem. I added also the opkg build to the target. The opkg package may be usable, i did not tested it realy! The start/stop functionality is yet completely not implemented! So if you have some ideas for the correct implementation feel free to build it. So there is to copy the client.conf.example to /etc/openvpn, or even testing if there is some config, the loaded kernelmodul and so on. Remind: !!! You need the tun.ko kernelmodul to get proper working openvpn !!! Stefan Seyfried <seife_at_tuxbox-git_dot_slipkontur_dot_de> 2011-07-03 add debian-on-coolstream documentation --->8