優化 Git Commit 流程:AI 助你寫出完美訊息!

優化 Git Commit 流程:AI 助你寫出完美訊息!

步驟概述

  1. 使用 git diff 生成變更摘要
  2. 利用 AI 分析差異並生成 commit 訊息建議
    ( 可以搭配 Cursor 降低手動成本 )
  3. 根據團隊規範調整 AI 生成的 commit 訊息

詳細步驟與範例

1. 使用 git diff 生成變更摘要

package.json 中根據需求添加自定義腳本:

"scripts": {
  "diff": "git diff --staged > diff_output.txt",
  "diff-branch": "git diff origin/dev... > diff_branch_output.txt"
}

使用方法:

npm run diff
# 或
npm run diff-branch

2. AI 分析與 Commit 訊息生成

範例:假設我們對 src/components/UserProfile.tsx 進行了以下修改:

- const UserProfile = ({ name, email }) => {
+ const UserProfile = ({ name, email, avatar }) => {
   return (
     <div>
       <h2>{name}</h2>
       <p>{email}</p>
+      {avatar && <img src={avatar} alt={`${name}'s avatar`} />}
     </div>
   );
 };

將這個 diff 提供給 AI,可能會得到如下的 commit 訊息建議:

feat(component): Add avatar support to UserProfile

- Update UserProfile component to accept 'avatar' prop
- Render avatar image when provided
- Improve user interface with visual representation

This change enhances the UserProfile component by adding support for
user avatars, providing a more complete and visually appealing user
representation.

3. 調整 AI 生成的 Commit 訊息

根據團隊規範,我們可能需要進行以下調整:

  1. 添加 issue 編號
  2. 使用特定的 commit 類型前綴
  3. 限制標題長度

調整後的 commit 訊息:

feat(UserProfile): Add avatar support #123

- Accept 'avatar' prop
- Render avatar image when provided
- Enhance UI with visual user representation

自定義 AI 提示以符合團隊規範

為了讓 AI 生成的 commit 訊息更符合團隊規範,可以自定義 AI 提示。例如:

請根據以下規則生成 git commit 訊息:
1. 使用 conventional commits 格式
2. commit 類型限定為:feat, fix, docs, style, refactor, test, chore
3. 範疇(scope)使用括號包裹,並使用 PascalCase
4. 標題不超過 50 個字符
5. 正文每行不超過 72 個字符

我目前是建立了一個.cursorrules在專案下
作為全域的提示詞,讓團隊成員都可以使用

When I ask about git commit messages
Please refer to the relevant information in ./diff_output.txt
and following the rules:

1. Always answer me in Traditional Chinese, eg: title, steps and explain
2. write message and sub-description in English
3. Use the "conventionalCommits" format
4. Add scope in the following format
   ["layout","page","component","ui","hook","asset","style","api","slice","action","util","data","config","package"]
5. if the message mention about component name or file name, please use `` to wrap it, and ignore the file extension if its a file name.
6. Also list the corresponding files for each commit
7. please split commit if needed. eg: by feature or scope. following the git commit best practice.
8. provide the git command for each commit
9. Write Clear and Descriptive Messages: Your commit messages should be explaining what the commit does and why you made the change.
10. Descriptive Commit Message: A descriptive commit message clearly explains what the commit does and why the change was made. It should provide enough context for others (and your future self) to understand the change without reading the code.
11. prevent the repetitive description and point out the key feature.

---

When I ask about git merge request (MR)
Please refer to the relevant information in ./diff_branch_output.txt
and following the rules:

1. explain in Traditional Chinese
2. if mention about component name, file name, function name, feature name..., write in English and use `` to wrap it
3. Write Clear and Descriptive Messages: Your commit messages should be explaining what the commit does and why you made the change.
4. Descriptive Commit Message: A descriptive commit message clearly explains what the commit does and why the change was made. It should provide enough context for others (and your future self) to understand the change without reading the code.
5. Prevent the repetitive description and point out the key feature,and example.
6. Order by high priority. especially shared-component or component widely use, and effect others.
7. Provide a detailed and concise description of the proposed changes. Clearly explain the problem being addressed, the solution implemented, and any potential impacts. This helps reviewers understand the context and evaluate the changes more effectively.

---

實際應用案例

案例 1:重構 API 調用

假設我們對 src/api/userService.ts 進行了以下修改:

- import axios from 'axios';
+ import api from './apiClient';

- export const fetchUser = (id) => axios.get(`/api/users/${id}`);
+ export const fetchUser = (id) => api.get(`/users/${id}`);

- export const updateUser = (id, data) => axios.put(`/api/users/${id}`, data);
+ export const updateUser = (id, data) => api.put(`/users/${id}`, data);

AI 生成的 commit 訊息:

refactor(ApiClient): Centralize API calls using apiClient

- Replace direct axios usage with custom apiClient
- Update fetchUser and updateUser functions
- Improve consistency and maintainability of API calls

This change centralizes our API call mechanism, making it easier to
manage headers, interceptors, and base URLs across the application.

Closes #456

案例 2:新增功能

假設我們在 src/components/TodoList.tsx 中添加了篩選功能:

+ import { useState } from 'react';

  const TodoList = ({ todos }) => {
+   const [filter, setFilter] = useState('all');
+
+   const filteredTodos = todos.filter(todo => {
+     if (filter === 'active') return !todo.completed;
+     if (filter === 'completed') return todo.completed;
+     return true;
+   });

    return (
      <div>
+       <div>
+         <button onClick={() => setFilter('all')}>All</button>
+         <button onClick={() => setFilter('active')}>Active</button>
+         <button onClick={() => setFilter('completed')}>Completed</button>
+       </div>
-       {todos.map(todo => (
+       {filteredTodos.map(todo => (
          <TodoItem key={todo.id} {...todo} />
        ))}
      </div>
    );
  };

AI 生成的 commit 訊息:

feat(TodoList): Add filtering functionality

- Implement state management for filter
- Add filter buttons for all, active, and completed todos
- Apply filtering logic to displayed todos

This enhancement allows users to easily filter their todo list,
improving the overall user experience and task management capabilities.

Closes #789

Merge Request

以下是一個我用 AI 輔助產生 Merge Request 的實際範例
可以大致描述這次 branch 的合併
做了什麼主要變更,或是註記可能影響的範圍

範例一

主要變更

  1. Token 處理和存儲

    • 新增 setToken 工具函數,同時儲存 access token 跟 refresh token
    • 更新 GoogleLoginButtonSSOfetchLoginThunk 以使用新的 setToken 函數
    • 在 localStorage 中存儲 userId,用於 refresh token
  2. 身份驗證邏輯

    • 實現 useAuth hook,集中處理身份驗證檢查
    • 更新 Workspace 組件,使用 useAuth hook
  3. Token 刷新機制

    • 新增 getNewAccessTokenToken 函數處理 token 刷新
    • errorHandler 中實現 401 錯誤的 token 刷新邏輯
    • 添加隊列機制,處理 refresh token 期間的多個請求
  4. 類型定義和接口

    • 新增 RefreshToken 接口和 clientType 枚舉
    • 更新現有接口,refresh token
  5. API 請求處理

    • 更新 Axios 攔截器,使用新的 refresh token 機制
    • 改進錯誤處理和日誌記錄

範例二

主要變更

1. ManagerPage 組件優化

  • 改進了頁面布局和樣式
  • 優化了 Notes 和地理坐標信息的顯示方式clock-in
  • 添加了 TimeSheetAction 組件,替換原有的 Add 按鈕
    • (TimeSheetAction 包含 CreateRecordDialogCreateTimeOffDialog 組件)

2. ManagerPageTable 組件增強

  • 新增了 Role 列,顯示 user 在 project 中的身分
  • 優化了 Notes 列的顯示,增加了 text overflow 處理

也可以自己再手動加上 but ticket 單號,或是待修正列表的編號

3. FlexPane 組件調整

  • 更改了組件的定位方式,提高了可用性 (1.5.1 版面超過空間)
  • 調整了 Edit 按鈕的標籤文本 (3.10.8 Edit 文字顯示錯誤)

4. BaseTable 共用組件重構

  • 移除了內置的DeleteButton,改從頁面各自的 data 處理
  • 單一表格內如果有想傳入的 prop 或 className,可透過CellsProp傳入

5. 其他組件和頁面的改進

  • 更新了 BaseFlexPaneHeaderBaseAttachmentCard BackgoundImage 都改用 Next Image 來提升效能

6. API 和數據處理優化

  • 優化了 memberAPItimesheetAPI 中 RTKQuery 的 data cache invalid 處理 (3.10.9欄位送出時資料要更新)