So generieren Sie aussagekräftige Commits. Wenden Sie den Standard für konventionelle Commits an



Vertrautes Chaos in den Namen von Commits. Ein bekanntes Bild?

Sicher kennen Sie Git-Flow . Dies ist eine großartige Reihe von Verzweigungskonventionen in Git. Es ist gut dokumentiert und weit verbreitet. Normalerweise sind wir mit der richtigen Verzweigung vertraut und sprechen viel darüber, aber leider widmen wir dem Problem der Benennung von Commits zu wenig Aufmerksamkeit, weshalb Nachrichten in Git oft willkürlich geschrieben werden.

Mein Name ist Yerzhan Tashbenbetov, ich arbeite in einem der Yandex.Market-Teams. Und heute werde ich Habrs Lesern sagen, mit welchen Tools wir in einem Team sinnvolle Commits erstellen. Ich lade Sie ein, an der Diskussion zu diesem Thema teilzunehmen.


Die mangelnde Übereinstimmung bei der Benennung von Commits macht es schwierig, mit der Geschichte in Git zu arbeiten. Das war in unserem Team. Bevor gemeinsame Regeln für alle verwendet und die Automatisierung implementiert wurden, sahen typische Commits wie folgt aus:

SECRETMRKT-700:     , . SECRETMRKT-701, SECRETMRKT-702:     ... 

Zunächst schrieb jeder Entwickler Nachrichten, wie er wollte: Jemand beschrieb die Aufgabe, jemand listete die vorgenommenen Änderungen auf, jemand verwendete einen Zufallsgenerator. Alles war uneins. Zweitens verkürzten Aufgabennummern, die in Commits vorhanden waren, häufig nützlichen Text. All dies machte es schwierig, effektiv mit der Geschichte in Git zu arbeiten.

Aus diesem Grund haben wir den Standard für konventionelle Commits im Team implementiert, Commits im Commitizen des Konsolendienstprogramms generiert und das Ergebnis mit Commitlint überprüft . Infolgedessen haben sich die Commits geändert und sehen folgendermaßen aus:

 refactor(tutorial):      feat(products):      fix(products):      

Das Lesen der Geschichte und das Erkennen der Änderungen wurde einfacher. Wir haben uns nicht geweigert, Aufgabennummern anzugeben, sondern alles wurde gemäß der Konvention für konventionelle Commits ordentlich in Commits verschoben.

Als nächstes zeige ich Ihnen, wie Sie eine ähnliche Reihenfolge in Git erreichen.



Best Practices, Empfehlungen und allgemeine Lösungen für die Benennung von Commits


Wenn Sie versuchen zu verstehen, welche Praktiken in der Branche verwendet werden, finden Sie folgende Optionen:

  • Artikel mit allgemeinen Tipps zum Schreiben von Commits. Zum größten Teil sind sie ziemlich logisch und eröffnen ein gutes Thema, aber es gibt ein Gefühl der Unordnung und das Fehlen einer umfassenden Lösung für das Problem.
  • Standards für das Schreiben von Commits. Es gibt nur wenige von ihnen. Es handelt sich um Dokumente mit einer klaren Liste von Regeln, die häufig speziell für eine große Bibliothek oder ein großes Framework geschrieben wurden. Diese Standards überzeugen durch einen systematischen Ansatz, Popularität und Unterstützung in der Open-Source-Community.

Wir brauchen mehr Ordnung in Commits!

Die Methode der konventionellen Commits unterscheidet sich von anderen Standards und verdient aus mehreren Gründen eine eingehende Prüfung:

  1. Es ist gut dokumentiert und gestaltet. Die Spezifikation bietet Antworten auf die häufigsten Fragen.
  2. Die Urheber der Konvention ließen sich von den Anforderungen für das Schreiben von Commits inspirieren, die im beliebten und bewährten AngularJS-Framework verwendet werden .
  3. Den Konventionsregeln folgen mehrere große und beliebte Open-Source-Bibliotheken (wie yargs und lerna ).
  4. Außerdem werde ich mich auf die automatische Erstellung von Versionshinweisen und Änderungsprotokollen vorbereiten.

Ein Beispiel für ein Commit zu diesem Standard:

 fix(products):             -     .  : SECRETMRKT-578, SECRETMRKT-602 



Wichtige Punkte konventioneller Commits


  • Der Entwickler muss die folgende Festschreibungsstruktur einhalten:
    <type> (<scope>): <subject>

    <body>

    <Fußzeile>
  • Das Commit sollte eine Kopfzeile, möglicherweise einen Text und eine Fußzeile haben.
  • Der Header des Commits sollte mit einem Typ beginnen, der die Besonderheiten der an der Codebasis vorgenommenen Änderungen angibt, und mit einer Beschreibung enden.
  • Neben der obligatorischen Leistung fix (deren Verwendung streng geregelt ist) sind auch andere Typen zulässig.
  • Ein Commit kann einen Gültigkeitsbereich haben . Es kennzeichnet einen Code, der von den Änderungen betroffen ist. Der Bereich folgt der Art des Commits. Die Norm regelt keine klare Liste von Bereichen. Beispiele für Bereiche: Eslint, Git, Analytics usw.
  • Die Commit-Beschreibung sollte unmittelbar nach dem Typ / Bereich stehen.
  • Der Hauptteil des Commits kann verwendet werden, um einen Drilldown zu Änderungen durchzuführen. Der Körper sollte durch eine leere Zeile von der Beschreibung getrennt sein.
  • Die Fußzeile sollte verwendet werden, um externe Links, den Kontext des Commits oder andere Metainformationen anzugeben. Die Fußzeile sollte durch eine leere Linie vom Körper getrennt sein.


Zusätzlich zu den in der Konvention aufgeführten Regeln verwenden wir die folgenden populären Empfehlungen:


  • Im Hauptteil des Commits schreiben wir, was geändert wurde und warum .
  • Wir verwenden die folgenden Arten von Commits:
    bauenErstellen Sie ein Projekt oder ändern Sie externe Abhängigkeiten
    ciCI-Konfiguration und Skripterstellung
    docsAktualisierung der Dokumentation
    featNeue Funktionen hinzufügen
    behebenFehlerbehebung
    perfÄnderungen zur Leistungsverbesserung
    RefactorBearbeiten von Code ohne Beheben von Fehlern oder Hinzufügen neuer Funktionen
    zurücksetzenRollback zu vorherigen Commits
    StilÄnderungen im Codestil (Tabulatoren, Einrückungen, Punkte, Kommas usw.)
    TestTests hinzufügen
  • Wir schreiben die Beschreibung in zwingender Stimmung , genau wie Git selbst.
    Zweig 'fix / SECRETMRKT-749-fix-Tippfehler-in-Titeln' zusammenführen '
  • Laden Sie die Commit-Beschreibung nicht mit Satzzeichen hoch.




Standard für konventionelle Commits, der von Lerna- Mitwirkenden verwendet wird



Wie wechsle ich einfach zum richtigen Namen der Commits?


Automatisierung und Komfort müssen hinzugefügt werden. Um dieses Problem zu lösen, benötigen wir zwei Tools: den Commit-Generator und den Commit-Wurf, die so konfiguriert sind, dass sie vor dem Push an das Repository überprüft werden.



Richten Sie das Commitizen-Dienstprogramm ein


Mit diesem Tool können Sie Commits mithilfe des integrierten Assistenten generieren. Darüber hinaus wird Commitizen von der Community gut unterstützt und ist dank zusätzlicher Module in hohem Maße anpassbar.

  1. Installieren Sie das Commitizen- Dienstprogramm global (möglicherweise benötigen Sie Administratorrechte).

     npm i -g commitizen 
  2. Installieren Sie als Nächstes den an cz anpassbaren Adapter. Es ist erforderlich, die Vorlage mit Fragen zu konfigurieren, die vom Commitizen- Dienstprogramm verwendet werden.

     npm i -D cz-customizable 
  3. Lassen Sie uns die Datei commitizen.js erstellen, die zur Konfiguration von cz-anpassbar benötigt wird. Legen Sie die erstellte Datei im Verzeichnis ./config/git ab. Ich empfehle, das Projektstammverzeichnis nicht mit Konfigurationsdateien zu verunreinigen und zu versuchen, die Dateien in einem dafür vorbereiteten Ordner zu gruppieren. Inhalt:

    Zeigen Sie commitizen.js an
     "use strict"; module.exports = { //         types: [ { value: "build", name: "build:      " }, { value: "ci", name: "ci:  CI    " }, { value: "docs", name: "docs:  " }, { value: "feat", name: "feat:   " }, { value: "fix", name: "fix:  " }, { value: "perf", name: "perf:     " }, { value: "refactor", name: "refactor:         " }, { value: "revert", name: "revert:    " }, { value: "style", name: "style:    (, , ,   ..)" }, { value: "test", name: "test:  " } ], // .    ,    scopes: [ { name: "components" }, { name: "tutorial" }, { name: "catalog" }, { name: "product" } ], //         (  'fix') /* scopeOverrides: { fix: [ {name: 'style'}, {name: 'e2eTest'}, {name: 'unitTest'} ] }, */ //    messages: { type: "   ?", scope: "\n ,    ():", //   allowCustomScopes  true customScope: "  :", subject: "     :\n", body: '   ().  "|"   :\n', breaking: " BREAKING CHANGES ():\n", footer: "    (,   ). : SECRETMRKT-700, SECRETMRKT-800:\n", confirmCommit: "   ?" }, //    allowCustomScopes: true, //   Breaking Changes allowBreakingChanges: false, //     footerPrefix: " :", // limit subject length subjectLimit: 72 }; 


  4. Fügen Sie Links zu cz-customizable und der zuvor erstellten Konfigurationsdatei in package.json hinzu:

    Zeige einen Teil von package.json
     { "config": { "commitizen": { "path": "node_modules/cz-customizable" }, "cz-customizable": { "config": "config/git/commitizen.js" } }, } 

  5. Lassen Sie uns das Ergebnis überprüfen. Geben Sie den folgenden Befehl in das Terminal ein:

     git cz 

Der Commitizen-Assistent sammelt zuerst Informationen über den Typ und den Bereich des Commits, fordert dann nacheinander den Text an, der in der Beschreibung, im Text, in der Fußzeile enthalten ist, und erstellt nach Ihrer Zustimmung ein Commit.

Schauen Sie sich unbedingt das Beispiel des konfigurierten Commitizen-Dienstprogramms und des daran angeschlossenen cz-cusomizable-Adapters an



Richten Sie Husky- und Commitlint-Dienstprogramme ein


  1. Installieren Sie Husky und Commitlint im Projekt:

     npm i -D husky @commitlint/cli 
  2. Mit Husky fügen wir einen Commit-Check hinzu. Fügen Sie dazu in package.json unmittelbar nach den Skripten den folgenden Hook hinzu und geben Sie darin einen Link zur Datei commitlint.js an:

    Zeige einen Teil von package.json
     { "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "husky": { "hooks": { "commit-msg": "commitlint -E HUSKY_GIT_PARAMS -g './config/git/commitlint.js'" } }, "devDependencies": { "@commitlint/cli": "^7.2.1", "husky": "^1.1.3", } 


  3. Erstellen Sie die Datei commitlint.js, damit der Linter ordnungsgemäß funktioniert. Legen Sie die erstellte Datei im Verzeichnis ./config/git ab. Dateiinhalt:

    Zeigen Sie commitlint.js an
     //     @commitlint/config-conventional module.exports = { rules: { //        "body-leading-blank": [2, "always"], //         "footer-leading-blank": [2, "always"], //    72  "header-max-length": [2, "always", 72], //       "scope-case": [2, "always", "lower-case"], //      "subject-empty": [2, "never"], //     '.' "subject-full-stop": [2, "never", "."], //       "type-case": [2, "always", "lower-case"], //      "type-empty": [2, "never"], //      "type-enum": [ 2, "always", [ "build", "ci", "docs", "feat", "fix", "perf", "refactor", "revert", "style", "test" ] ] } }; 



Das ist alles. Jetzt werden alle Commits überprüft, bevor sie an das Repository gesendet werden :)

Sehen Sie sich unbedingt das Beispiel des konfigurierten Commitlint-Dienstprogramms an



Was soll man also als Commitizen oder Commitlint wählen?


Beide! Zusammen bringen sie hervorragende Ergebnisse: Der erste generiert Commits, der zweite überprüft sie.


Warum empfehlen Standards die Verwendung von Imperativen?


Dies ist eine äußerst interessante Frage. Ein Commit ist eine Codeänderung. Eine Nachricht in einem Commit kann als Anweisung zum Ändern dieses Codes angesehen werden. Machen, ändern, hinzufügen, aktualisieren, reparieren - all dies sind spezifische Anweisungen für den Entwickler.

Im Git- Versionsverwaltungssystem selbst wird übrigens Imperativ empfohlen:

 [[imperative-mood]] Describe your changes in imperative mood, eg "make xyzzy do frotz" instead of "[This patch] makes xyzzy do frotz" or "[I] changed xyzzy to do frotz", as if you are giving orders to the codebase to change its behavior. 


Warum sich an irgendwelche Konventionen halten? Lohnt sich die Zeit? Was ist der Gewinn?


Es lohnt sich. Im Allgemeinen bemerkte ich, dass wir eher bereit waren, die an der Codebasis vorgenommenen Änderungen detailliert darzustellen. Im Hauptteil des Commits beschreiben wir detailliert, warum wir diese oder jene Lösungen verwenden mussten. Das Verständnis der Geschichte ist objektiv einfacher geworden. Außerdem entwickelt sich unser Produkt weiter und wir erwarten Nachschub im Team. Ich bin sicher, dass es Anfängern dank der Einführung des Standards und der Automatisierung leichter fällt, sich in den Entwicklungsprozess zu integrieren.

Versuchen Sie, das Ergebnis zu teilen.


Nützliche Links:


Source: https://habr.com/ru/post/de431432/


All Articles