Gitのcommit messageを書くには
必要な情報としては変更点に関する記述なのでgit diffの結果を見て何が変わったかを書けば良い、
という比較的形式的にはわかりやすいものです。
コマンドラインからChatGPTを簡単に使えるツールを作ったのでそこにgit diffの結果を与えて
いい感じのcommit messageを考えてもらえば良さそう。
git-gpt-commit
gitのサブコマンドとしてgpt-commitというコマンドを追加するツールです。
コミットメッセージをあらかじめ用意する以外は基本的にgit commitと同じように使えて、
-aとかオプションもそのまま使えます。
中身は簡単なシェルスクリプトです。
準備
インストール
インストールはHomebrewを使っていれば
1
| |
これで chatgpt-prompt-wrapper も依存先として一緒にインストールされます。
直接入れる場合はbinディレクトリにあるgit-gpt-commitを
PATH下に置けばgit gpt-comitが使えるようになります。
ただし、直接入れる場合は chatgpt-prompt-wrapper も手動でいれる必要があります。
その他の準備
chatgpt-prompt-wrapper を使うにあたってOpenAIのAPI Keyが必要になります。
OpenAIでアカウントを作って ここ からAPI Keyを取得して 環境変数として
1
| |
のように設定しておきます。
使い方
何かしら変更を行ったレポジトリの中で、変更したファイルをgit addして
1
| |
とすると、ChatGPTがgit diff を見て考えたcommit messageがあらかじめ書かれた状態で
commit messageの編集画面に入ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
`
こんな感じのメッセージが準備された状態になります。
あとはこれを適当に編集して保存すればcommit出来ます。
オプション設定
commitメッセージを作るための命令
デフォルトでは以下のようなプロンプトを使っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
命令部分
まず、命令部分ですが、ここは好きに設定すべきところではありますが、 ここではSemantic Commit Messages を使って書き方を指示しています。
こういった形の形式張った書き方はアルゴリズム相手には相性が良いのでいい感じにまとめてくれます。
この部分は設定で変えることが出来て、PROMPTという環境変数に指示を書いておくと
上の### diffより上の部分を置き換えることができます。
または~/.config/git_gpt_commit/config(もしXDG_CONFIG_HOMEが指定されていたらそれの下のgit_gpt_commit/config)
に設定を書いておけばそれが反映されます。
日本語で、
1
| |
とかでもOK。
diffの出力
最後の部分でgit diffを渡しています。
--cachedでaddしたものとHEADとの比較をします。
もし-aが渡された場合には先にgit add -uを実行して変更があったファイルをaddするようにしているので、
これで必ず必要な部分のdiffが取れるようになっています。
また、$exclude_listが渡されていますが、これはデフォルトでは
1
| |
になっています。 poetry.lockとかGemfile.lockとか、パッケージを管理するlockファイルは 1つパッケージを変更しただけでも依存関係で大きく内容が変わってしまいますが その変更を逐次確認してcommit messageに入れることは通常無いと思うので省いています。
特にgpt-3.5-turboだとlockファイルの変更だけでもtoken数の制限にかかっちゃたりもするので。
もし排除するファイルを変更したい倍には
EXCLUDEという環境変数に設定します。もしくは
configに書きます。
上のデフォルトは
1
| |
となっています。
:(exclude)$(git rev-parse --show-toplevel)は勝手に追加されます。
複数指定したい場合は
1
| |
のような感じでコンマ区切りで。
1
| |
のように展開されます。
テンプレートメッセージ
上の例だと入ってませんが、.gitconfigなどでcommit.templateを指定して
commit message編集時に表示させるようにしている場合これも準備されたcommit messagesの下に表示されるようになっています。
別途git gpt-commitのときは別のテンプレートを使いたい場合は
MESSAGEという環境変数に設定、もしくは
configに書きます。
MESSAGEを設定しない場合にcommit.templateが設定されているとそれを使いますが、
MESSAGE=""のように空にすればテンプレートはひょうじされなくなります。
ChatGPTモデル
chatgpt-prompt-wrapper
では現在デフォルトでgpt-3.5-turboを使うようになっていますが、
git-gpt-commitでは
MODELという環境変数にgpt-4とか指定すればモデルを変更できます。
-c/–changeオプション
追記: 2023/04/19
-c/--changeというオプションを追加しました。
これに続いて今回のcommitの概要てきなものを教えてあげる事ができます。
例えばこの変更を入れたときに使ったものが上の例ですが、
何も指定せずgit gpt-commitだと
1
| |
というメッセージになってchangeオプションという部分は入ってますが、まず、最初がrefactorになっているし
文章もちょっと意味が分かりません。
これに対して、
1
| |
とすると
1
| |
となり、これはそのまま使えるレベルです。
日本語で、
1
| |
と入れても同じドラフトが出来ました。
どうやってるかというと、-c/--changeのオプションがあるとその内容を
PROMPTの前に
1
| |
という形で加えるようにしてあるだけです。
あまり詳細に書けるならそのままメッセージを書けば良いじゃん、ということで恩恵が浅いですが、
上のadd ...程度を書いてちゃんとした文章に直してくれるのであれば
結構使う意味はあるんじゃないかな、と。
追記ここまで
その他
コミットのキャンセル
commit messageをエディタで開いた状態からやっぱりやめたい場合には
#でコメントアウトしてある部分以外を全て削除して終了すればキャンセルになります。
(--allow-empty-messageを設定していない限り。)
この際、git gpt-commit -aのようにstageされてないものもaddするようになっていても、
キャンセル時にはaddしたものだけgit restore --stagedで戻すようになっています。
pre-commit
pre-commitをインストールしている場合にはChatGPTに送る前にpre-commit単独で走らせてチェックして 失敗した場合にはその場でcommitを辞めるようにしています。
alias
git gpt-commitはちょっと長いので、個人的には~/.gitconfigに
1 2 | |
としてgit cコマンドとして使ってます。実際よく使うのはgit c -a。
gcにしたかったけどgit-gcは最初からあるので、1文字コマンドは微妙かと思いつつ他に良いのもないのでcで。
aicommits
gpt-3.5のAPIが使えるようになってわりかしすぐに出来ていた同じようなcommit message作成ツール。
この中では
1
| |
みたいなプロンプトが使われています。
オプションで変えられる言語のためのlocaleという変数とgit diffの結果のdiffという変数が入っていますが、
簡潔にまとめよ、的な感じの命令です。
このあたりの命令部分を自分で決めたかったのと、
APIを使う部分を外に出してgit commitの-mでメッセージのドラフトとして入れてすぐに編集出来る状態にした方が
やりやすいかな、ということでgit-gpt-commitを作ってみました。
多分ほかにも色々とあるとは思いますが、 プロンプト部分を簡単に変えられるのと、 API部分はchatgpt-prompt-wrapperにまかせてgit-gpt-commit自体はシンプルなので 好きなように変更して使ったりするにも良いんじゃないかな、と。
感想
ちょっとした変更だと編集なしでもOKなのが多いですが、 多少複雑だと手直ししたくなるのも多いので、 まだ完全自動というよりドラフトを書いてもらって すぐに手直しできる状態にするやり方が一番しっくりきています。
とりあえずこれ使ってcommitするようにしているので、意味のないfixとかupdateとかだけの
commitもだいぶ減らせて良い感じです。
あとはやっぱり自由に書かせるよりは Semantic Commit Messagesのようなある程度ちゃんとした決まりがあった方が 出来上がったものをそのまま使える状態になる確率が高いかな、という感じ。

