GitLensのコミットメッセージ自動生成機能で思い通りのフォーマットで生成されず、ハマった話

この記事はエムティーアイ アドベントカレンダ2024の12月22日分の記事です。 こんにちは、スマートコンテンツ事業部に所属している友末です。

目次

はじめに

コミットメッセージを自動生成する方法はいくつかあり、生成AIのツールはOpenAIやClaude等のAPIキーを利用して使うことが多いと思います。
そして、私の所属部署ではGitHub Copilotが導入されているのですが、APIキーを発行して使うというのはなかなか難しいのが現状です。(似たような方も多いのではないでしょうか?)
そこで、GitHub Copilotのモデルを使って、コミットメッセージを自動生成する方法があったので記事に残します。
本記事では、前半にGitHub Copilot+GitLensを使用してコミットメッセージを自動生成する方法、後半に自動生成で思い通りのフォーマットで生成されない時の対処方法を紹介します。

GitHub Copilot + GitLensを使用してコミットメッセージを自動生成する方法

GitLensのインストール

  1. VS Codeを開く
  2. 拡張機能タブを選択
  3. 検索バーに「GitLens」と入力
  4. GitLensをインストール

GitHub Copilot Chatのインストール

GitLens同様にGitHub Copilot Chatをインストールします。(GitHub Copilotも一緒にインストールされます)

GitHub Copilotへサインイン

GitHub CopilotをVSCodeで使用するために、サインインします。
サインインの方法は既に記事になっているものがありますので参考にしてください。
VSCode ではじめる GitHub Copilot 活用術

使用するAI Modelの設定

  1. F1を押してコマンドパレットを開く
  2. GitLens: Switch AI Modelと入力し、使用するModelを選択する(Copilotの欄がGitHub Copilotのモデルです)

GitHub Copilotのオプトアウト設定

自動生成の前にGitHub Copilotがオプトアウト(学習させない)設定になっているか確認しておきます。
※GitHub Copilot for Businessの場合は不要です
GitHub Copilotを使う ソースコードを学習させない設定と公式ドキュメントのリンク

実際にコミットメッセージを自動生成する

  1. ソース管理タブを選択
  2. 3点リーダーからGenerate Commit Message with GitLensを選択
    ※出てこない場合は設定からGitlens > Ai > Generate Commit Message: Enabledにチェックが入っているか確認する。

無事コミットメッセージが生成されました!

フォーマットされたコミットメッセージを生成する

生成されるコミットメッセージを、いつも使っているフォーマットに設定します。 設定からGitlens > Ai > Generate Commit Message: Custom Instructionsにフォーマットの指示を入力します。
※settings.jsonからも入力できます。
その場合"gitlens.ai.generateCommitMessage.customInstructions":に指示を入力します。

私はMOD: #XXXXX: Add: {summary}のようなフォーマットにしてほしいので以下の指示を入力しました。

Now, create a commit message.The message should be formatted as:MOD: #XXXXX: {prefix}: {summary}Where:- {prefix} should be in PascalCase (e.g. Update, Add, Fix)- {summary} should be a brief description (max 100 chars)Output only the formatted message.

もう一度コミットメッセージを生成します。

概ねフォーマット通りですが、説明が長くなっています。また、指示に従わないこともあります。なぜこのようなことが起こるのでしょうか。

思い通りのフォーマットで生成されない時の対処方法

思い通りのフォーマットで生成されない場合は、まず以下の2点を試します。

  • 英語で指示をしているか
  • Now, create a commit message.で始めているか(理由は後ほど説明します)

根本原因はGitLens のプロンプトにあり、これを理解して指示を作成する必要があります。
GitLens はオープンソースソフトウェア(OSS)のため、GitHub で実際のコードを見ると、prompts.ts でGitLensも指示を出しているようです。 番号が振ってある部分を翻訳すると以下です。

  1. 差分とコンテキストを慎重に分析し、以下に焦点を当てる:
    • 変更の目的と根拠
    • 解決された問題や導入されたメリット
    • 重要なロジックの変更やアルゴリズムの改善
  2. コミットメッセージを作成する際は以下を確認する:
    • 変更の「理由」、そのメリット、または解決する問題を強調する
    • informal だが professional なトーンを使用する
    • 未来志向で、三人称単数現在形を使用する(例:「修正する」「更新する」「改善する」「追加する」「削除する」)
    • 明確かつ簡潔にする
    • 差分とコンテキストから意味のある情報のみを統合する
    • 理解に不可欠でない限り、コード、特定のコード識別子、名前、ファイル名の出力を避ける
    • 情報の繰り返し、広範な一般論、「これ」「このコミット」「この変更」などの不要な表現を避ける
  3. 変更の主な目的を1つの簡潔な文で要約し、コミットメッセージのサマリーとする
    • 三人称単数現在形の動詞で始める
    • 可能であれば50文字以内に制限する
  4. 必要に応じて、変更の簡単な説明を提供し、コミットメッセージの本文とする
    • 読みやすさと独立した考えを分けるために改行を追加する
    • 変更の「何を」ではなく「なぜ」に焦点を当てる
  5. 変更が特定の問題やチケットに関連している場合、コミットメッセージの最後に参照を含める
    (例:「Fixes #123」または「Relates to JIRA-456」)

重要な部分を要約すると、必要に応じて簡単な説明を提供するとあるので余計な説明が追加されていたということになります。
また、先ほど設定したGenerate Commit Message: Custom Instructionsprompts.ts > generateCommitMessageUserPrompt内の一番下\${instructions}に代入されるようです。
代入の結果、完成したプロンプト内で矛盾が発生していると、上手くコミットメッセージが生成されないようです。
例)私の指示 > フォーマット以外は出力しない ≠ GitLensの指示 > 必要があれば説明をつけて

Now, create a commit message.で始めているか

これは、代入部分で接続詞のような働きをしてくれ、うまくコミットメッセージが生成されるからではないかと考えています。

GitLensのコードを書きかえて思い通りのフォーマットで生成する(応用)

※ここから先は、発展的な内容となります

私の場合、先ほどまでの対処法で解決しなかったので、GitLensのコードをクローンして自分用にカスタマイズしようと思います。

GitLensをローカルで使えるようにセットアップ

セットアップについてはGitLens > CONTRIBUTING.mdに詳しい記載があります。

  1. クローンする(Zipでダウンロードしてもok)
    git clone https://github.com/gitkraken/vscode-gitlens.git

  2. 依存関係をインストールする
    pnpm install

  3. ビルドする
    pnpm run rebuild

prompts.tsを編集

prompts.tsのgenerateCommitMessageUserPromptで補足説明部分などを削除して、フォーマットが適用されるように編集します。
例)

export const generateCommitMessageUserPrompt = `You are tasked with summarizing code changes into a concise but meaningful commit message. You will be provided with a code diff and optional additional context. Your goal is to analyze the changes and create a clear, informative commit message that accurately represents the modifications made to the code.

First, examine the following code changes provided in Git diff format:
<~~diff~~>
\${diff}
</~~diff~~>

Now, if provided, use this context to understand the motivation behind the changes and any relevant background information:
<~~additional-context~~>
\${context}
</~~additional-context~~>

To create an effective commit message, follow these steps:

1. Carefully analyze the diff and context, focusing on:
   - The purpose and rationale of the changes
   - Any problems addressed or benefits introduced
   - Any significant logic changes or algorithmic improvements
2. Ensure the following when composing the commit message:
   - Emphasize the 'why' of the change, its benefits, or the problem it addresses
   - Use an informal yet professional tone
   - Use a future-oriented manner, third-person singular present tense (e.g., 'Fixes', 'Updates', 'Improves', 'Adds', 'Removes')
   - Be clear and concise
   - Synthesize only meaningful information from the diff and context
   - Avoid outputting code, specific code identifiers, names, or file names unless crucial for understanding
   - Avoid repeating information, broad generalities, and unnecessary phrases like "this", "this commit", or "this change"
3. Summarize the main purpose of the changes in a single, concise sentence, which will be the summary of your commit message
   - Start with a third-person singular present tense verb

4. Add "MOD: #XXXXX" at the beginning of the commit message to identify which issue it relates to. Then, add a prefix followed by the commit message.
   - {prefix} should be in PascalCase (e.g. Update, Add, Fix)

Describe the commit message summary within the <summary> tag in 150~200 characters or less, without excessive explanation or additional text.
Do not output anything other than the <summary> tag.

Example format:

<summary>
MOD: #XXXXX: {prefix} Implements user authentication feature
</summary>

\${instructions}

Now, based on the provided code diff and any additional context, create a concise but meaningful commit message following the instructions above.`;

実際にコミットメッセージを自動生成する

  1. 再度ビルドする(クイックビルド)
    pnpm run build

  2. F5キーを押してデバッグする

  3. 3点リーダーからGenerate Commit Message with GitLensを選択

無事思い通りのフォーマットで生成することができました。
(CONTRIBUTING.md > Bundlingにはパッケージ化方法の記載がありますので、これで自分の環境に適用、同僚に配布することができます。)

終わりに

今回はGitLensでフォーマットされたコミットメッセージの生成方法について、記事にしました。
後半の応用については、あまり現実的ではないかもしれませんが、興味のある方はぜひお試しください。