修复异常git commit信息,是否需要对所有关联分支都执行git rebase?
Git多分支包含问题提交的修复方案
核心结论
你对Git commit不可变的理解是正确的,但仅修改master分支的提交无法让其他分支自动同步修复,原因如下:
- 交互式rebase修改commit message的操作不会改动原问题commit对象,只会生成一个哈希值完全不同的新提交,仅master分支的指针会移动到新提交链上
- 其他包含原问题commit的分支,提交链依然绑定原问题commit对象,只要该对象还存在任何引用,就会一直保存在仓库中,访问时依然会拖慢服务器
可选处理方案
方案1:不重写历史(推荐团队协作场景使用)
不需要修改任何分支的提交历史,不会造成协作者本地冲突,操作如下:
- 基于原问题commit生成修复了提交信息的新commit,记录新commit的哈希值(记为
new_commit_hash),同时记录原问题commit的哈希值(记为bad_commit_hash) - 执行替换命令:
git replace <bad_commit_hash> <new_commit_hash> - 将替换规则推送到远程仓库:
git push origin 'refs/replace/*'
该规则生效后,Git在任何场景访问原问题commit都会自动映射到修复后的新commit,服务器加载提交信息时不会再读取到10万行的冗余内容。
方案2:重写历史(仅适合个人仓库或团队统一协商后使用)
如果要彻底清除原问题commit,需要处理所有包含该提交的分支:
- 先在master分支完成交互式rebase,替换问题commit为修复后的版本
- 对每一个包含原问题commit的其他分支,执行嫁接命令:
git rebase --onto <bad_commit_hash>^ <bad_commit_hash> <target_branch_name> - 所有分支处理完成后,强制推送所有修改过的分支到远程
- 通知所有协作者删除本地对应旧分支,重新拉取远程分支,避免合并操作把原问题commit重新带回仓库
- 仓库无任何引用指向原问题commit后,执行
git gc --prune=all即可彻底清除该对象
内容的提问来源于stack exchange,提问作者Wassinger
相关产品推荐
相关产品推荐

