﻿# 介紹好用工具：CodeGPT (使用 GPT 自動化產生 Git 的 Commit Log 訊息)

各位可能已經知道 [Visual Studio Code v1.84](https://code.visualstudio.com/updates/v1_84#_github-copilot) 與 [GitHub Copilot Chat](https://docs.github.com/en/copilot/github-copilot-chat/about-github-copilot-chat) 最近內建了一個 [Commit message generation](https://code.visualstudio.com/updates/v1_84#_commit-message-generation) 功能，可以自動產生 Git Commit 需要的 Log，不過我覺得第一版功能相當殘缺，常常言不及義，也不能客製化提示內容(Prompts)，不太好用。我自己則是找到一套 [CodeGPT](https://github.com/appleboy/CodeGPT) 工具來幫我做到一樣的事，用了一段時間覺得真的相當實用，所以打算透過這篇文章介紹給大家。

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/stwillblogassets.blob.core.windows.net/cf92d9b3099f6dd240c5-059e2733-1154-425b-b573-9dac5aee094a.webp)

### 安裝 CodeGPT 命令列工具

-   在 Windows 上用 [Chocolatey](https://chocolatey.org/) 安裝
    
    ```bash
    choco install codegpt -y
    ```
    
    > 這個在 Chocolatey 上面的 [codegpt](https://community.chocolatey.org/packages/codegpt) 套件是我建立的。
    
-   在 MacOS 上用 [Homebrew](http://brew.sh/) 安裝
    
    ```bash
    brew tap appleboy/tap
    brew install codegpt
    ```
    
-   直接透過 Go 從 Source code 直接安裝
    
    ```bash
    go install github.com/appleboy/CodeGPT/cmd/codegpt@latest
    ```
    

安裝好之後可以查詢看看版本資訊：

```bash
codegpt version
```

```
version: 0.7.0 commit: 450ad28
```

### 初始化設定 CodeGPT 命令列工具

由於 CodeGPT 會需要呼叫 OpenAI 或 Azure OpenAI Service 的 API 才能運作，所以我們需要先設定好 API Key 才行，也因此使用時會有一點點成本。

-   設定 OpenAI 的 [API Key](https://platform.openai.com/account/api-keys)
    
    ```bash
    codegpt config set openai.provider "openai"
    codegpt config set openai.api_key "sk-xxxxxxx"
    ```
    
-   設定 Azure OpenAI Service 的 [API Key](https://platform.openai.com/account/api-keys)
    
    ```bash
    codegpt config set openai.provider "azure"
    codegpt config set openai.base_url "https://<your-resource-name>.openai.azure.com/"
    codegpt config set openai.api_key "your-api-key"
    ```
    

接下來則是要設定你想要選用什麼 GPT 模型，目前 CodeGPT 支援的模型有：

-   `gpt-4-32k-0314`
-   `gpt-4-32k`
-   `gpt-4-0314`
-   `gpt-4`
-   `gpt-3.5-turbo` (預設值)
-   `gpt-3.5-turbo-0301`
-   `text-davinci-003`
-   `text-davinci-002`
-   `text-davinci-001`
-   `text-curie-001`
-   `text-babbage-001`
-   `text-ada-001`
-   `davinci-instruct-be`
-   `davinci`
-   `curie-instruct-beta`
-   `curie`
-   `ada`
-   `babbage`

由於 CodeGPT 預設選用 `gpt-3.5-turbo` 模型，該模型只能支援 `4,096 tokens` 而已，對於 Commit 時稍微多一點內容，一下子就不夠用了，因此我個人是選用 `gpt-4-32k` 模型。如果你也要調整的話，記得做出以下設定，這點相當重要：

```bash
codegpt config set openai.model "gpt-4-32k"
codegpt config set openai.model_name "gpt-4-32k"
```

由於在 Azure OpenAI Service 上面可以部署多種模型，可以指定模型名稱，所以你還要額外指定 `openai.model_name` 設定：

```bash
codegpt config set openai.model_name "gpt-4-32k"
```

接著則是調整預設呼叫 API 的 Timeout 時間，預設的 10 秒我覺得太短了，當你在做 Code Review 任務時經常不夠，所以我改成 30 秒：

```bash
codegpt config set openai.timeout "30s"
```

再來是調整預設的 `max_tokens` 數量，預設的 `300` tokens 我也是覺得太少了，所以我改成 `1000` tokens：

```bash
codegpt config set openai.max_tokens 1000
```

最後是調整預設的 `git diff` 結果顯示的上下文行數，預設的 `3` 行我也覺得太少了，所以我改成 `5` 行：

```bash
codegpt config set git.diff_unified 5
```

由於作者是台灣人，這套 CodeGPT 工具有提供多國語言的支援，預設是英文(`en`)，如果你想要改成繁體中文(`zh-tw`)的話，可以透過以下命令：

```bash
codegpt config set output.lang "zh-tw"
```

這幾個參數設定完後，基本上就很完美了！👍

你可以用 `codegpt config list` 命令查詢目前設定的參數：

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/5783fdf0963970275689-e474bdbd-95c7-4020-a922-2165a9f1e837.png)

### 使用 CodeGPT 來產生 Commit 訊息

由於這是一套命令列工具，所以使用上不但非常簡單，靈活性也很高，有很多參數可以用。以下是幾種常見的使用情境：

1.  查看用法
    
    ```bash
    codegpt --help
    ```
    
2.  預覽產生的 Commit 訊息
    
    ```bash
    codegpt commit --preview
    ```
    
    ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/e86bed94f5b21177aa57-60e4f5ad-2d63-493f-af05-29cebd87b036.png)
    
    這個過程會幫你寫入 `.git/COMMIT_EDITMSG`，因此你可以用 `git commit -F .git/COMMIT_EDITMSG` 命令直接沿用該訊息。
    
3.  直接透過 CodeGPT 來 Commit
    
    如果你可以信任 CodeGPT 產生的 Commit 訊息，那倒是可以直接就 Commit 了，方便很多！
    
    ```bash
    codegpt commit
    ```
    
    記得執行完後可以用 `git log -1` 看一下 Commit 訊息是否有問題，你隨時可以透過 `git commit --amend` 再次調整！
    
    或者，你可以在 Commit 產生之後用以下命令再次透過 CodeGPT 產生一遍新的內容：
    
    ```bash
    codegpt commit --amend
    ```
    
    > 因為 CodeGPT 預設的 Temperature 參數設定為 `1`，所以是 GPT 的「創意」模式，每次產生的 Commit 訊息多多少少會有一點差異。
    
4.  提供更完整的上下文，方便產生更精準的 Commit Message
    
    你可以試試這個命令，預設在做 `git diff` 比對差異時，他會顯示變更行的上下各 3 行讓你進行比較：
    
    ```bash
    git diff --staged
    ```
    
    事實上你可以調整變更行的上下的行數：
    
    ```bash
    git diff --staged --unified=5
    ```
    
    然而 CodeGPT 也支援這樣的調整，幫助你更好的判斷出變更內容的上下文，你可以透過 `--diff_unified` 參數來調整：
    
    ```bash
    codegpt commit --preview --diff_unified 5
    ```
    
5.  僅顯示送到 GPT 的提示內容 (Prompt Text)
    
    我喜歡 CodeGPT 的一個最主要原因，就是他是開放原始碼，而且可以讓我調整 Prompt 內容，如果有問題我可以隨時調校！👍
    
    你可以透過 `--prompt_only` 參數來查看送到 GPT 的 Prompt 內容，真的太佛心！
    
    ```bash
    codegpt commit --prompt_only
    ```
    
6.  排除某些檔案
    
    有些較大的變更，或是變更內容包含許多無意義的檔案或內容，把這些內容送到 GPT 也無法分析，所以我們可以透過 `--exclude_list` 參數來排除這些檔案，例如：
    
    ```bash
    codegpt commit --preview --exclude_list 'README.md,images/*'
    ```
    
    > 多個檔案就用逗號分隔，檔名路徑可以包含萬用字元！
    
    我看了一下 CodeGPT 的[原始碼](https://github.com/appleboy/CodeGPT/blob/97b30b25b46e25ac96c7c18e8fc8e70eb367e095/git/git.go#L34-L34)，我發現他用了一個 `git diff --help` 官方文件沒寫的技巧，蠻神奇的！上述命令其實會轉成以下命令：
    
    ```bash
    # 簡寫
    git diff --staged -- . ':!README.md' ':!images/*'
    
    # 完整語法
    git diff --staged -- . ':(exclude)README.md' ':(exclude)images/*'
    ```
    

### 使用 CodeGPT 來產生 Code Review 報告

這套 CodeGPT 還有一個很實用的功能，那就是他可以針對你這次的 Commit 內容，產生一份 Code Review 報告，讓你可以快速的檢視這次的變更內容，這個功能我覺得非常實用！

1.  產生 Code Review 報告
    
    ```bash
    codegpt review
    ```
    
2.  將報告翻譯成「繁體中文」版
    
    ```bash
    codegpt review --lang zh-tw
    ```
    
    > 由於是透過 GPT 翻譯的關係，內容不是特別到位，而且偶爾會出現簡體字或大陸地區常用的詞彙。
    

### 使用 CodeGPT 來設定 `prepare-commit-msg` hook

從 Visual Studio Code v1.69 開始，有個 `git.useEditorAsCommitInput` 設定 (預設為 `true`)，可以讓使用者在 VS Code 的原始碼控制(Source Control)功能中，在不輸入任何 Message 的情況下按下 Commit 按鈕時，直接開啟 VS Code 的編輯器來編輯 Commit Message 內容。

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/793f87562ddf77b44fcc-6182ca10-9e47-4a74-a287-67dd4d317ef5.png)

這個新功能最棒的地方就在於，我們只要搭配 [git prepare-commit-msg hook](https://git-scm.com/docs/githooks) 就可以自動呼喚 CodeGPT 來產生 commit message 了！

這個功能當然也內建在 CodeGPT 之中，你只要在專案中輸入以下命令就可以自動安裝好：

```bash
codegpt hook install
```

![codegpt hook install](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/66b8388d2a4f4ebb8c7c-632576f3-0525-4bd5-85bf-3119336fb273.png)

這個命令會自動建立一個 `./.git/hooks/prepare-commit-msg` Git Hook 檔案，檔案內容如下：

```bash
#!/bin/sh

codegpt commit --file $1 --preview
```

> 這裡的 `$1` 是 Git Hook 的參數，代表的是 Git Commit Message 檔案的路徑，通常是 `.git/COMMIT_EDITMSG` 檔案。

所以實際上在 Commit 時會這樣：

1.  先等待 CodeGPT 3 ~ 5 秒鐘產生 Commit Message
    
    ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/6837a0a726ffda1cbf79-98c006f0-7526-41af-9555-72375d841cf4.png)
    
2.  然後就會自動開啟編輯器讓你編輯 Commit Message，不喜歡你還可以手動調整！
    
    ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/1102e95b0570fa87422e-d4418584-dd48-4919-a115-df08b705ef4d.png)
    
3.  編輯完畢後，按下 `Ctrl+S` 儲存，然後關閉編輯器，就會自動 Commit 了！
    

補充說明一下，VS Code 還有一個 `git.showCommitInput` 設定，如果你將這個設定關閉的話，就可以把 Source Control tab 中的 Message 欄位整個隱藏 (如下圖示)，只留下 Commit 按鈕，這樣就可以完全使用 CodeGPT 來產生 Commit Message 了！

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/github.com/dedb9d402644cf3bf089-76282de3-d238-4604-bf22-4d40af716abf.png)

### 總結

目前為止 [CodeGPT](https://github.com/appleboy/CodeGPT) 是我嘗試過最好的 Git 訊息自動產生工具，而且是開放原始碼專案，喜歡這種開放、透明的感覺，使用起來也比較安心。我覺得這個工具非常實用，如果你也覺得實用的話，不妨給作者一個 [Star](https://github.com/appleboy/CodeGPT) 吧！👍

### 相關連結

-   [appleboy/CodeGPT](https://github.com/appleboy/CodeGPT): A CLI written in Go language that writes git commit messages or do a code review brief for you using ChatGPT AI (gpt-4, gpt-3.5-turbo model) and automatically installs a git prepare-commit-msg hook.
-   [Author commit message using an editor - Visual Studio Code June 2022](https://code.visualstudio.com/updates/v1_69#_author-commit-message-using-an-editor)
-   [git - Why does the COMMIT\_EDITMSG open when I try to commit in vscode? - Stack Overflow](https://stackoverflow.com/q/72908270/910074)
