开发一个git cli提交助手
我们可以把这个工具做得更专业、更像一个正规的 CLI 工具。我们可以支持自动读取本地 .env 配置、流式打印响应(看起来更酷炫),并且能够直接通过全局命令或 git m 触发。
下面是为您量身定制的完整开发步骤,采用目前性价比最高且完全兼容 OpenAI 格式的 DeepSeek API 作为示例(若使用其他模型,只需替换 BASE_URL 和 MODEL)。
第一步:初始化项目
在本地找一个目录(例如 ~/projects/git-m-cli),初始化并安装必要的依赖。我们不需要复杂的框架,使用 Node.js 原生的 child_process 和官方的 openai SDK 即可。
bash
mkdir git-m-cli && cd git-m-cli
npm init -y
# 安装 OpenAI 官方 SDK(用于兼容调用各种大模型)以及用于读取配置的 dotenv
npm install openai dotenv
请谨慎使用此类代码。
打开 package.json,在根节点添加 "type": "module",以便我们使用现代的 import 语法:
json
{
"name": "git-m-cli",
"version": "1.0.0",
"type": "module",
...
}
请谨慎使用此类代码。
第二步:创建配置文件
在项目根目录下创建一个 .env 文件,用来存放你的 API Key 和配置(避免把密钥硬编码在代码里):
env
# 大模型 API 配置(以 DeepSeek 为例,也可以换成 OpenAI/Ollama 等)
AI_API_KEY=你的_DEEPSEEK_API_KEY
AI_BASE_URL=https://deepseek.com
AI_MODEL=deepseek-chat
请谨慎使用此类代码。
第三步:编写核心 CLI 脚本
在项目根目录下创建一个 index.js 文件,写入以下完整代码:
javascript
#!/usr/bin/env node
import { execSync } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';
import OpenAI from 'openai';
import dotenv from 'dotenv';
// 1. 加载配置(支持读取脚本所在目录的 .env 文件)
const __dirname = path.dirname(fileURLToPath(import.meta.url));
dotenv.config({ path: path.join(__dirname, '.env') });
const { AI_API_KEY, AI_BASE_URL, AI_MODEL } = process.env;
if (!AI_API_KEY) {
console.error('❌ 错误: 未在 .env 文件中检测到 AI_API_KEY!');
process.exit(1);
}
// 初始化 OpenAI 客户端
const openai = new OpenAI({
apiKey: AI_API_KEY,
baseURL: AI_BASE_URL || 'https://deepseek.com',
});
async function main() {
try {
// 2. 获取暂存区的代码差异 (Diff)
let diff = '';
try {
diff = execSync('git diff --cached').toString().trim();
} catch (e) {
console.error('❌ 错误: 当前目录似乎不是一个 Git 仓库。');
process.exit(1);
}
if (!diff) {
console.log('⚠️ 提示: 没有发现已暂存(Staged)的文件,请先运行 `git add` 暂存你的改动。');
process.exit(0);
}
console.log('🤖 正在分析暂存区代码并生成备注...\n');
// 3. 构建 Prompt
const prompt = `你是一个专业的 Git 提交助手。请根据以下代码的 diff 内容,生成一条精炼、准确、结构清晰的 Git commit message。
请严格使用 Angular 规范格式(例如: feat(scope): add something 或 fix: resolve bug)。
不要输出任何解释性文本、不要包裹 markdown 代码块(如 \`\`\`),只输出 commit message 本身。
---
${diff.slice(0, 5000)}
---`;
// 4. 调用大模型(开启流式传输,让体验更丝滑)
const stream = await openai.chat.completions.create({
model: AI_MODEL || 'deepseek-chat',
messages: [{ role: 'user', content: prompt }],
temperature: 0.1, // 降低随机性,使输出更稳定
stream: true,
});
let commitMessage = '';
process.stdout.write('📝 AI 建议的备注: ');
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || '';
commitMessage += content;
process.stdout.write(content); // 实时打印生成的字符
}
process.stdout.write('\n\n');
commitMessage = commitMessage.trim();
if (!commitMessage) {
console.error('❌ 错误: AI 未能生成有效的备注。');
process.exit(1);
}
// 5. 执行真正的 Git Commit
console.log('🚀 正在提交到 Git...');
// 使用带引标的字符串,防止备注中的特殊字符引发终端解析错误
execSync(`git commit -m "${commitMessage.replace(/"/g, '\\"')}"`, { stdio: 'inherit' });
console.log('\n✅ 提交成功!');
} catch (error) {
console.error('\n❌ 发生异常:', error.message);
process.exit(1);
}
}
main();
请谨慎使用此类代码。
第四步:配置 Git 别名与权限
我们要让系统和 Git 认识这个脚本。
赋予脚本执行权限:
bash
chmod +x index.js请谨慎使用此类代码。
配置 Git 别名:
由于 Git 原生不支持git -m这种带横杠的二级参数作为命令(-m在 git 中默认是message的参数标识),最符合直觉的替代方案是配置为git m。在终端运行以下命令(请将路径替换为你本地index.js的绝对路径):bash
git config --global alias.m "!node /你的绝对路径/git-m-cli/index.js"请谨慎使用此类代码。
🎯 体验测试
现在,前往你任何一个开发中的 Git 项目:
bash
# 1. 修改一些代码,然后暂存
git add .
# 2. 见证奇迹的时刻
git m
请谨慎使用此类代码。
控制台将会流式打印出:
text
🤖 正在分析暂存区代码并生成备注...
📝 AI 建议的备注: feat(auth): implement jwt modern token verification
🚀 正在提交到 Git...
[main 7fa3bc2] feat(auth): implement jwt modern token verification
2 files changed, 45 insertions(+), 5 deletions(-)
✅ 提交成功!
请谨慎使用此类代码。
为了让这个小工具在你的日常开发中更实用,你是否需要增加以下功能:
自动加入检查机制:如果 AI 生成的备注不满意,允许在终端输入
y/n来决定是否确认提交或重新生成?自动运行
git add .:连git add都不想敲,直接输入git m一键暂存并提交所有修改?更改为其他大模型(如本地部署的 Ollama)?