コミットの名前のなじみのある混乱。 おなじみの写真?
確かにgit-flowを知っています。 これは、Gitの優れた分岐規則です。 十分に文書化され、広く配布されています。 通常、私たちは正しい分岐に精通しており、それについて多くのことを話しますが、残念ながら、コミットの命名の問題にはあまり注意を払っていません。
私の名前はYerzhan Tashbenbetovです。Yandex.Marketチームの1つで働いています。 そして今日、Habrの読者に、チームで意味のあるコミットを作成するために使用するツールを教えます。 このトピックに関するディスカッションにご参加ください。
コミットの命名に関する合意がないため、Gitで履歴を操作することが難しくなります。 これは私たちのチームでした。 すべてに共通のルールを使用して自動化を実装する前に、典型的なコミットは次のようになりました。
SECRETMRKT-700: , . SECRETMRKT-701, SECRETMRKT-702: ...
最初に、各開発者が望みどおりにメッセージを作成しました。誰かがタスクを説明し、誰かが変更をリストし、誰かがランダムフレーズジェネレータを使用しました。 すべてが対立していた。 第二に、コミットに存在するタスク番号は、しばしば有用なテキストを短縮しました。 これはすべて、Gitの履歴を効果的に操作することを妨げました。
このため、チームに従来のコミット標準を実装し、コンソールユーティリティcommitizenでコミットの生成を開始し、 commitlintを使用して結果を確認しました 。 その結果、コミットが変更され、次のようになります。
refactor(tutorial): feat(products): fix(products):
ストーリーを読み、変更を認識することで簡単になりました。 タスク番号の指定を拒否しませんでした; 従来のコミット規則に従って、すべてがコミットにきちんと移動されました。
次に、Gitで同様の順序を実現する方法を説明します。
コミットの命名に関するベストプラクティス、推奨事項、および一般的なソリューション
業界で使用されているプラクティスを把握しようとすると、次のオプションが見つかります。
- コミットを書くための一般的なヒントを含む記事。 ほとんどの場合、彼らは非常に論理的であり、良いトピックを開きますが、混乱の感覚と問題に対する包括的な解決策の欠如があります。
- コミットを書くための標準。 それらのいくつかがあります。 それらは、明確なルールのリストを備えたドキュメントであり、大規模なライブラリまたはフレームワーク用に特別に記述されていることがよくあります。 これらの標準は、オープンソースコミュニティでの体系的なアプローチ、人気、サポートに感銘を受けます。
コミットにはさらに順序が必要です!
従来のコミット方法論は他の標準から際立っており、いくつかの理由から綿密な調査に値します。
- 十分に文書化され、設計されています。 その仕様は、最も一般的な質問に対する回答を提供します。
- コンベンションの作成者は、人気のある実績のあるAngularJSフレームワークで使用されているコミットを書くための要件に触発されました。
- 規則の後には、いくつかの大規模で人気のあるオープンソースライブラリ( yargsやlernaなど )が続きます。
- 利点には、リリースノートと変更ログの自動作成の準備が含まれます。
この標準へのコミットの例:
fix(products): - . : SECRETMRKT-578, SECRETMRKT-602
従来のコミットのキーポイント
- 開発者は次のコミット構造に従う必要があります。
<タイプ>(<スコープ>):<サブジェクト>
<本体>
<フッター> - コミットには、ヘッダー、おそらく本文とフッターが必要です。
- コミットのヘッダーは、コードベースに加えられた変更の詳細を示すタイプで始まり、説明で終わる必要があります。
- 必須の特技 、 修正 (その使用は厳密に規制されています)に加えて、他のタイプも許可されています。
- コミットにはスコープを設定できます 。 変更の影響を受けたコードを特徴づけます。 領域は、コミットのタイプに従います。 この規格は、明確な地域のリストを規制していません。 エリアの例:eslint、git、analyticsなど。
- コミットの説明は、タイプ/エリアの直後にある必要があります。
- コミットの本文を使用して、変更の詳細を確認できます。 本文は、空行で説明から分離する必要があります。
- フッターは、外部リンク、コミットのコンテキスト、またはその他のメタ情報を指定するために使用する必要があります。 フッターは、空の行で本文から分離する必要があります。
規則にリストされている規則に加えて、次の一般的な推奨事項を使用します。
- コミットの本文に、変更された内容とその理由を記述します 。
- 次のタイプのコミットを使用します。
建てる プロジェクトをビルドするか、外部の依存関係を変更します ci CI構成およびスクリプト docs ドキュメントの更新 偉業 新しい機能を追加する 修正する バグ修正 性能 パフォーマンス改善の変更 リファクタリング バグを修正したり、新機能を追加したりせずにコードを編集する 元に戻す 前のコミットへのロールバック スタイル コードスタイル(タブ、インデント、ピリオド、カンマなど)による編集 テストする テストを追加する - 説明は、Git自体と同じように、 命令的な雰囲気で記述します。
マージブランチ 'fix / SECRETMRKT-749-fix-typos-in-titles'
- 句読点付きのコミットの説明をアップロードしないでください。
lernaが使用する従来のコミット標準
単純に正しい名前のコミットに切り替える方法は?
自動化と利便性を追加する必要があります。 この問題を解決するには、リポジトリにプッシュする前に確認するように構成されたコミットジェネレーターとコミットリターの2つのツールが必要です。
commitizenユーティリティをセットアップする
このツールを使用すると、組み込みのウィザードを使用してコミットを生成できます。 さらに、commitizenはコミュニティによって十分にサポートされており、追加モジュールのおかげで高度にカスタマイズ可能です。
- commitizenユーティリティをグローバルにインストールします(管理者権限が必要な場合があります)。
npm i -g commitizen
- 次に、 cz-customizableアダプターをインストールします。 commitizenユーティリティで使用される質問でテンプレートを構成する必要があります。
npm i -D cz-customizable
- commitizen.jsファイルを作成しましょう。cz-customizableを設定する必要があります。 作成したファイルを./config/gitディレクトリに配置します。 プロジェクトルートに構成ファイルを散らかさないようにし、このために準備されたフォルダーにファイルをグループ化することをお勧めします。 内容:
commitizen.jsを表示"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 };
- package.jsonでcz-customizableおよび以前に作成した構成ファイルへのリンクを追加します。
package.jsonの一部を表示{ "config": { "commitizen": { "path": "node_modules/cz-customizable" }, "cz-customizable": { "config": "config/git/commitizen.js" } }, }
- 結果を確認しましょう。 ターミナルで次のコマンドを入力します。
git cz
commitizenウィザードは、最初にタイプ、コミットの領域に関する情報を収集し、次に説明、本文、フッターに含まれるテキストを順番に要求し、同意後、コミットを作成します。
設定されたcommitizenユーティリティとそれに接続されたcz-cusomizableアダプタの例を必ず確認してください
ハスキーおよびcommitlintユーティリティをセットアップする
- ハスキーとcommitlintをプロジェクトにインストールします。
npm i -D husky @commitlint/cli
- ハスキーでは、コミットチェックを追加します。 これを行うには、package.jsonで、スクリプトの直後に次のフックを追加し、その中にcommitlint.jsファイルへのリンクを指定します。
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", }
- リンターが正しく機能するために必要なcommitlint.jsファイルを作成します。 作成したファイルを./config/gitディレクトリに配置します。 ファイルの内容:
commitlint.jsを表示// @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" ] ] } };
それだけです これで、リポジトリに送信する前にすべてのコミットがチェックされます:)
設定されたcommitlintユーティリティの例を必ず確認してください。
では、commitizenまたはcommitlintを選択するのは何ですか?
それと、もう一つ! 併せて、それらは優れた結果をもたらします。最初はコミットを生成し、2番目はそれらをチェックします。
なぜ標準では命令型の使用が推奨されているのですか?
これは非常に興味深い質問です。 コミットはコードの変更であり、コミット内のメッセージはこのコードを変更するための指示と見なすことができます。 作成、変更、追加、更新、修正-これらはすべて開発者向けの特定の指示です。
ところで、 Gitのバージョン管理システム自体では、命令型が推奨されています 。
[[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.
慣習に固執するのはなぜですか? それは時間の価値がありますか? 利益はいくらですか?
それだけの価値。 一般に、コードベースに加えられた変更を詳細に説明することに積極的になったことに気付きました。 コミットの本文では、これらのソリューションまたはそれらのソリューションを使用しなければならなかった理由を詳細に説明します。 履歴の理解が客観的に簡単になりました。 さらに、当社の製品は開発中であり、チームでの補充が期待されています。 標準と自動化の導入により、初心者が開発プロセスに統合しやすくなると確信しています。
結果を試して共有してください。