
【实践手记】Git重写已提交代码历史信息
需求背景:项目与常用git配置信息(全局)不一致,应在git仓库中进行非全局配置,但已有三四次提交推送到了远程仓库中。需要修改Git项目中已提交代码的作者信息,包括本地未推送的提交和已推送到远程仓库的历史记录。
⚠注意
本文所描述的情形并非一般生产环境常用的方法,此方法对代码仓库存在危害,非特殊需求不要采取这样的操作。
- 此操作会重写Git历史记录,所有提交的SHA值都会改变
- 需要强制推送到远程仓库
- 仅在小团队、个人项目或项目早期中使用
- 如有其他协作者,应确保团队成员了解此变更
- 准备回滚方案
⚠Git官方文档的警告
git filter-branch 存在大量隐患,可能会对预期的历史重写产生不明显的误差(而且由于其性能糟糕,你几乎没有时间去研究这些问题)。 这些安全和性能问题无法向后兼容修复,因此不建议使用。 请使用其他历史过滤工具,如 git filter-repo。 如果您仍然需要使用 git filter-branch,请仔细阅读 安全性(和 性能)以了解 filter-branch 的隐患,然后尽可能合理地避免其中列出的危险。
操作步骤
1. 检查当前配置
# 查看当前项目的git配置
git config --list --local
# 查看当前提交历史和作者信息
git log --pretty=format:"%h %an <%ae> %s" -5
2. 配置新的作者信息(仅对当前项目)
# 设置新的用户名和邮箱(仅对当前项目生效)
git config user.name "新用户名"
git config user.email "新邮箱@example.com"
# 验证配置
git config --list --local | grep user
3. 修改历史记录中的作者信息
# 使用git filter-branch批量修改所有提交的作者信息
git filter-branch --env-filter '
OLD_EMAIL="旧邮箱@example.com"
CORRECT_NAME="新用户名"
CORRECT_EMAIL="新邮箱@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
4. 验证修改结果
# 检查修改后的提交记录
git log --pretty=format:"%h %an <%ae> %s" -5
# 查看最近几次提交
git log --oneline -3
5. 推送到远程仓库
# 使用强制推送更新远程仓库(建议使用--force-with-lease更安全)
git push --force-with-lease origin main
# 或者使用普通强制推送(风险更高)
git push --force origin main
6. 清理临时文件
# 删除git filter-branch产生的临时文件
rm -rf .git/refs/original/
# Windows PowerShell版本
Remove-Item -Recurse -Force .git/refs/original/ -ErrorAction SilentlyContinue
变更验证
本地验证:
# 查看提交历史
git log --oneline -10
# 查看作者信息
git log --pretty=format:"%h %an <%ae> %s" -10
# 检查当前配置
git config user.name
git config user.email
远程验证:检查远程仓库的作者信息是否正确更新
其它方案
如果需求变更并没有上面描述的常见特殊,可以采用下面更安全的替代方案。
仅修改最后一次提交
bash git commit --amend --author="新用户名 <新邮箱@example.com>"
使用git filter-repo(推荐)
现代替代方案,比filter-branch更安全:
# 手动安装git filter-repo
pip install git-filter-repo
# 修改作者信息
git filter-repo --mailmap mailmap.txt
mailmap.txt文件格式:
新用户名 <新邮箱@example.com> <旧邮箱@example.com>
参考阅读
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 光溯星河
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果