DEV Community

Cover image for 使用 AI 自動生成 Git Commit 訊息
Let's Write
Let's Write

Posted on • Originally published at letswrite.tw

使用 AI 自動生成 Git Commit 訊息

使用 AI 自動生成 Git Commit 訊息

本篇要解決的問題

每次更新完成式碼,比如修 Bug、開發新功能後,在寫 Git Commit 訊息時都會很懶,基本上寫出的就是當下的自己看得懂,但未來的自己,或是接手的人不一定看得懂的狀態,導致之後要回頭查某次的更新時,會耗掉很長的時間在找哪次的更新是不是有改某某功能。

人類不想花心力的工作,就交給 AI 去作。

August 用了 OpenAI API,再用便宜的 gpt-4o-mini 模型後,Commit 訊息可以秒生成。

因為用的是 API,會需要付費使用,但 gpt-4o-mini 真的便宜,猛用一個月搞不好用不到 1 美金。

會看到這篇筆記文的,應該都是開發一段時間過的攻城獅大大們,所以才也想要省掉寫 Git Commit 的心力,這篇就不細寫了,因為方式很簡單,本篇不再贅述細節,僅附上相關文章連結供參考。


準備好必要東西:OpenAI API Key

因為是調用 OpenAI API 來幫我們寫提交訊息,因此需要 Key。

要再次提醒,使用 AI 來寫提交訊息,是要酷 $$ 的,只是選對模型,可以很省錢。

這個步驟前幾篇有寫過,就不再重寫,請看:

CodiumAI PR-Agent,在 GitLab 上用 AI 來 Code Review


準備好必要的東西:安裝 Node.js

這篇其實也可以跳過的,前端攻城獅的電腦,沒有安裝 Node.js 的可能性比搶到無敵星星還低。

這邊附上 Node.js 的官方網址,請自行下載安裝:https://nodejs.org/zh-tw

安裝後,可以用終端機執行以下,看是否安裝成功,有成功會回傳安裝的版本:

node -v
npm -v
Enter fullscreen mode Exit fullscreen mode

安裝必要的 packages

為了調用 OpenAI API,需要二個 package:axios、dotenv。

  • axios:用於處理 HTTP 請求,支援 Promise 和攔截器。
  • dotenv:用於從 .env 檔案載入環境變數,防止敏感資訊外洩。

看大家習慣用什麼工具安裝,這邊附上基本款的 npm install

npm install -D axios dotenv
Enter fullscreen mode Exit fullscreen mode

建立 .env 檔

.env 檔是拿來放 OpenAI API Key 用的,畢竟有了 Key,其他人就可以拿來用,為了保障我們 $$ 的生命安全,我們放進 .env 裡。

.env 檔內容如下:

OPEN_API_KEY_COMMIT=從 OpenAI 後台拿到的 Key
Enter fullscreen mode Exit fullscreen mode

.env 檔,除非專案是私人的,或是公司自架的 Git,不然要避免傳上去。


新增 commit.cjs 檔

這步驟,就是要寫調用 OpenAI API 來幫我們產生 commit 訊息的程式碼。

Prompt 的部份,是 August 試過幾次後,覺得有符合自己需求的寫法,如果大家發現有更好的 Prompt,歡迎留言提供。

commit.cjs 內容如下:

const axios = require('axios');
const { execSync } = require("child_process");
require('dotenv').config();
// 使用 OpenAI API Key
const apiKey = process.env.OPEN_API_KEY_COMMIT;
const apiUrl = 'https://api.openai.com/v1/chat/completions';
// 取得 git 差異內容
function getGitDiff() {
try {
// 首先獲取所有更改的檔案列表
const changedFiles = execSync("git diff --cached --name-only", { encoding: "utf-8" })
.split('\n')
.filter(file => file && !file.includes('.min.') && file.trim() !== '');
console.log('判斷檔案:', changedFiles);
// 然後只對這些檔案執行 git diff
const diff = changedFiles.map(file => {
try {
return execSync(`git diff --cached -- "${file}"`, { encoding: "utf-8" });
} catch (error) {
console.error(`Error getting diff for file ${file}:`, error);
return '';
}
}).join('\n');
return diff;
} catch (error) {
console.error("Error fetching git diff:", error);
return "";
}
}
// 使用 axios 調用 OpenAI 生成 commit 訊息
async function generateCommitMessage(diff) {
try {
const response = await axios.post(apiUrl, {
model: "gpt-4o-mini", // 使用 GPT-4 模型
messages: [
{
role: "system",
content: "你是一個優秀的開發者,負責撰寫簡潔又描述清楚的 Git commit 訊息。",
},
{
role: "user",
content: `根據以下的 git 差異生成一個有意義的 commit 繁體中文訊息,請包含兩個部分:\n1. Summary(不超過50字)\n2. Description(條列描述變更內容):\n${diff}`,
},
],
}, {
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
});
const commitMessage = Array.isArray(response.data.choices) && response.data.choices.length > 0 ? response.data.choices[0].message.content.trim() : "Default commit message.";
return commitMessage; // 回傳完整的 commit 訊息,不做拆解
} catch (error) {
console.error("Error generating commit message:", error.response ? error.response.data : error.message);
return "Refactor code."; // 如果發生錯誤,回傳一個預設的 commit 訊息
}
}
// 主執行流程
async function main() {
const diff = getGitDiff();
if (!diff) {
console.log("No changes to commit.");
return;
}
const commitMessage = await generateCommitMessage(diff);
console.log(commitMessage);
}
main();
view raw ai-commit.cjs hosted with ❤ by GitHub

程式碼裡,有避開去檢查 .min. 的檔案。

如果需要再避開什麼,就修改 filter 的部份,比方如果要再避掉 docs 資料夾中的文件,可以改為:

.filter(file => file && !file.includes('.min.') && !file.startsWith('docs/') && file.trim() !== '');
Enter fullscreen mode Exit fullscreen mode

使用方式

我們編輯好程式碼,將要 commit 的檔案 用 git add stage 以後,專案裡開啟終端機,輸入:

node commit.cjs
Enter fullscreen mode Exit fullscreen mode

接著幾需要幾秒的時間(看檔案異動的多寡),就會看見 OpenAI 回傳了這次的 commit message。

會像這樣:

OpenAI 回傳的範例 Git commit 訊息,包含 Summary 和 Description。

會提供兩個項目:簡短的 Summary、條例式也較詳細的 Description。

主要是因為大家使用 Git 的工具都不一樣,同事用 Sourcetree 就只有 Summary 可以填,但 August 用的是 Fork,就都可以填。

二項都列出來,大家自由選擇囉。

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay