如何批量改写Git分支mybranch中特定前缀的提交信息?
批量改写Git分支中特定提交信息的实现方法
当然可以实现,以下是三种可行方案:
一、Git原生命令(推荐用git filter-repo)
git filter-repo是官方推荐的批量修改提交历史工具,比旧的filter-branch更稳定高效。
步骤:
- 切换到目标分支:
git checkout mybranch
- 运行filter-repo命令,匹配以
🚀 build version开头的提交信息并追加指定后缀:
git filter-repo --message-callback ' if message.startswith(b"🚀 build version"): return message + b" ⚠️ (rebased since)" else: return message '
注意:部分Git版本默认包含git filter-repo,若未安装可通过包管理器或官方源码安装。执行命令前请确保仓库无未提交更改,建议先备份仓库。
二、Bash脚本自动化
如果需要更灵活的逻辑控制,可使用以下Bash脚本:
#!/bin/bash # 切换到目标分支,失败则退出 git checkout mybranch || exit 1 # 获取所有符合条件的提交哈希(按从旧到新顺序) commits=$(git log --reverse --format="%H" --grep="^🚀 build version") # 遍历提交,逐个修改信息 for commit in $commits; do # 获取原提交信息 original_msg=$(git log --format=%B -n 1 $commit) # 拼接新提交信息 new_msg="$original_msg ⚠️ (rebased since)" # 通过rebase修改提交信息 git rebase --onto $commit^ $commit --exec "git commit --amend -m '$new_msg'" done # 若需同步到远程仓库,取消注释下面一行 # git push origin mybranch --force
注意:此方法会逐个执行rebase操作,提交较多时耗时较长;推送远程仓库需使用
--force参数,因为提交历史已被改写。
三、TypeScript脚本(Deno/ts-node)
通过调用Git命令实现,以下是两种环境的示例:
Deno版本
import { exec } from "https://deno.land/x/exec/mod.ts"; async function modifyCommitMessages() { // 切换到目标分支 await exec("git checkout mybranch"); // 获取符合条件的提交哈希列表 const commitsOutput = await exec("git log --reverse --format=%H --grep='^🚀 build version'"); const commits = commitsOutput.stdout.trim().split("\n"); for (const commit of commits) { // 获取原提交信息 const originalMsgOutput = await exec(`git log --format=%B -n 1 ${commit}`); const originalMsg = originalMsgOutput.stdout.trim(); const newMsg = `${originalMsg} ⚠️ (rebased since)`; // 执行rebase修改提交信息 await exec(`git rebase --onto ${commit}^ ${commit} --exec "git commit --amend -m '${newMsg}'"`); } console.log("提交信息修改完成"); // 若需推送远程,取消注释下面一行 // await exec("git push origin mybranch --force"); } modifyCommitMessages().catch(err => console.error(err));
ts-node版本
import { exec } from "child_process"; import { promisify } from "util"; const execAsync = promisify(exec); async function modifyCommitMessages() { await execAsync("git checkout mybranch"); const commitsOutput = await execAsync("git log --reverse --format=%H --grep='^🚀 build version'"); const commits = commitsOutput.stdout.trim().split("\n"); for (const commit of commits) { const originalMsgOutput = await execAsync(`git log --format=%B -n 1 ${commit}`); const originalMsg = originalMsgOutput.stdout.trim(); const newMsg = `${originalMsg} ⚠️ (rebased since)`; await execAsync(`git rebase --onto ${commit}^ ${commit} --exec "git commit --amend -m '${newMsg}'"`); } console.log("提交信息修改完成"); // 若需推送远程,取消注释下面一行 // await execAsync("git push origin mybranch --force"); } modifyCommitMessages().catch(err => console.error(err));
注意:无论使用哪种脚本,执行前请确保仓库状态干净,且确认改写提交历史对团队协作的影响(需提前告知其他成员)。
内容的提问来源于stack exchange,提问作者Norfeldt
相关产品推荐
相关产品推荐

