在终端里用 AI 生成 Git 提交记录

random-pic-api

背景

在 IDEA 或其他开发工具里,生成 Git 提交记录已经是一件很简单的事情。

比如我在 IDEA 里会用 IntelliAI Changelog 插件,点一下图标,就可以让 AI 根据当前变更生成一条比较准确的 commit message。对日常开发来说,这个体验很顺手:不用手动翻 diff,也不用纠结这次到底该写 fixdocs 还是 chore

但到了终端里,事情就稍微麻烦一点。

我本机有不少本地仓库,不全是正式项目。有些是 Surge 配置,有些是 Wiki 知识库,有些是博客依赖目录,还有一些是个人小工具。它们都用 Git 记录变更历史,但我不想每个仓库都手写提交记录。

一开始最直接的办法,是把 staged diff 丢给 Claude:

1
2
3
4
5
6
7
8
git diff --cached | claude -p '
根据 git diff 生成一条中文 Conventional Commit message。
只输出 commit message,不要解释。
格式:
<type>(<scope>): <subject>

<body>
' > /tmp/commit-message.txt && git commit -F /tmp/commit-message.txt

这个脚本其实不长,也能用。

问题是,我有多个本地仓库都需要类似能力。每个仓库都复制一份 prompt,后面想改规则时又要到处同步,维护起来就有点烦。所以我最后还是决定封装一个通用脚本:在终端里直接用 AI 生成提交记录,不和某一个项目强绑定。


完善后的脚本

最终我把公共逻辑收敛到一个脚本里:

1
~/.local/bin/git-with-ai.sh

它做的事情很简单:

  1. 进入当前 Git 仓库;
  2. 默认执行 git add -A
  3. 读取暂存区文件列表、变更统计和部分 diff;
  4. 调用 AI 生成中文 Conventional Commit message;
  5. 清理 AI 偶尔输出的代码块、空行和多余说明;
  6. git commit -F 完成提交。

默认使用 Claude:

1
git-with-ai.sh

如果想切换工具,可以通过参数传入:

1
2
git-with-ai.sh --tool codex
git-with-ai.sh --tool gemini

为了兼容已有脚本,我也保留了显式提交信息:

1
git-with-ai.sh "docs: 更新说明"

这样一来,真正和仓库相关的 git-commit.sh 就可以非常薄,只负责进入自己的目录、调用公共脚本、最后 push:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#!/usr/bin/env bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$(realpath "$0")")" && pwd)"
cd "$SCRIPT_DIR" || exit 1

GIT_WITH_AI="${GIT_WITH_AI:-$HOME/.local/bin/git-with-ai.sh}"

if [[ ! -x "$GIT_WITH_AI" ]]; then
echo "未找到可执行的 git-with-ai.sh:$GIT_WITH_AI" >&2
exit 1
fi

"$GIT_WITH_AI" "$@"
git pull
git push -u origin main

这里有一个小细节:如果公共脚本发现没有可提交变更,我让它返回一个特殊状态码,比如 exit 10。由于项目脚本开启了 set -e,只要 git-with-ai.sh 返回非 0,后面的 git pullgit push 就不会继续执行。

而在 Makefile 里,我又给这些提交任务加了 || true,避免某个仓库没有变更或提交失败时影响后续任务:

1
dependencies/xxx/git-commit.sh --tool claude || true

这样行为就比较符合我的使用习惯:

  • 有变更:AI 生成提交记录,然后提交并推送;
  • 没有变更:当前仓库跳过,不继续 push;
  • 某个仓库失败:不影响后续仓库继续处理。

使用方式

日常单仓库使用时,直接在仓库里执行:

1
git-with-ai.sh

默认就是 Claude。

如果这次想用 Codex:

1
git-with-ai.sh --tool codex

如果想用 Gemini:

1
git-with-ai.sh --tool gemini

我还把 zsh 里的 gic 函数改成了一个薄封装:

1
2
3
gic() {
$HOME/.local/bin/git-with-ai.sh "$@"
}

所以平时在终端里可以直接敲:

1
2
3
gic
gic codex
gic --tool gemini

对于博客这种有多个依赖仓库的项目,我在 Makefile 里加了统一参数:

1
2
AI_COMMIT_TOOL ?= claude
AI_COMMIT_ARGS := --tool $(AI_COMMIT_TOOL)

于是批量提交时可以这样切换工具:

1
2
3
make commit-all
make commit-all AI_COMMIT_TOOL=codex
make commit-dependencies AI_COMMIT_TOOL=gemini

这个改动不复杂,但解决了一个很实际的问题:以后不管是博客、Wiki、Surge 配置,还是其他本地小仓库,只要是 Git 提交,都可以复用同一套 AI commit 逻辑。