自动化Git提交信息
在软件开发领域,编写一致且信息丰富的提交信息至关重要,但这一点经常被忽视。 这项任务可能变得乏味,特别是当您沉浸在编码流程中时。 为了帮助解决这个问题,我们精心设计了一个专门用于自动生成Git提交信息的脚本, 确保这些信息有意义并节省您的时间。
该脚本作为一个常规的node.js自动化脚本运行,使用runPrompt向LLM发起调用,并让用户确认生成的文本。
脚本说明
首先,我们检查Git仓库中是否有任何暂存的更改:
let { stdout } = await host.exec("git", ["diff", "--cached"])
如果没有暂存的更改,我们会询问用户是否想要暂存所有更改。如果用户确认,我们将暂存所有更改。否则,我们将中止操作。
const stage = await host.confirm("No staged changes. Stage all changes?", { default: true,})if (stage) { await host.exec("git", ["add", "."]) stdout = (await host.exec("git", ["diff", "--cached"])).stdout}if (!stdout) cancel("no staged changes")
我们使用暂存的更改生成初始提交信息:
message = ( await runPrompt( (_) => { _.def("GIT_DIFF", stdout, { maxTokens: 20000 }) _.$`GIT_DIFF is a diff of all staged changes, coming from the command:\`\`\`git diff --cached\`\`\`Please generate a concise, one-line commit message for these changes.- do NOT add quotes` }, { cache: false, temperature: 0.8 } )).text
上述提示配置表明,消息应当简洁明了,与“git diff —cached”输出相关,并且不应包含引号。
用户选择如何处理生成的消息:
choice = await host.select( message, [{ name: "commit", value: "commit", description: "accept message and commit" }, ...], )
提供了编辑或重新生成消息的选项。如果用户选择编辑消息,我们会要求他们输入新消息:
if (choice === "edit") { message = await host.input("Edit commit message", { required: true }) choice = "commit"}
如果用户选择提交消息,我们将提交更改:
if (choice === "commit" && message) { console.log((await host.exec("git", ["commit", "-m", message])).stdout)}
运行脚本
您可以通过CLI运行此脚本。
genaiscript run gcm
你可以将这个命令封装在gcm.sh
文件中,或者放在你的package.json文件的script
部分中:
{ "devDependencies": { "genaiscript": "*" }, "scripts": { "gcm": "genaiscript run gcm" }}
然后你可以使用以下命令运行脚本:
npm run gcm
使用git钩子
你也可以附加到commit-msg git钩子上按需运行消息生成。
使用huksy框架,我们可以在.husky/commit-msg
文件中注册genaiscript的执行。
commit-msg
钩子会接收存储提交消息的文件位置。我们将此参数传递给脚本,以便它填充到env.files
变量中。
genaiscript run commit-msg "$1"
在脚本中,我们检查文件内容是否已包含用户消息,否则生成新消息。
const msg = env.files[0] // file created by git to hold the messageconst msgContent = msg.content // check if the user added any message ?.split(/\n/g) .filter((l) => l && !/^#/.test(l)) // filter out comments .join("\n")if (msgContent) cancel("commit message already exists")
...
await host.writeText(msg.filename, message)
致谢
这个脚本的灵感来源于Karpathy的 commit message generator。