应优先使用 git rebase -i 修改最近几次提交邮箱,全量替换必须用 git filter-repo;git filter-branch 已弃用,git config 仅影响新提交,无法修改历史 commit 中的 author 字段。

别用 git filter-branch,它已被 Git 官方弃用,且极易出错;小范围改用 git rebase -i,全量改必须上 git filter-repo。
改最近几次提交的邮箱:用 git rebase -i 最稳
适合刚推错、还没被别人拉取、或只涉及本地分支前 5~10 次提交的场景。它不重写整个历史,风险可控,也不影响远古提交的 hash。
- 运行
git rebase -i HEAD~5(把5换成你要覆盖的提交数) - 在编辑器里把目标提交前的
pick改成edit,保存退出 - Git 停在第一个
edit提交后,执行:git commit --amend --author="Name <new>" --no-edit</new> - 再执行
git rebase --continue,重复直到所有edit提交处理完 - 如果已推送到远程,必须强制推送:
git push --force-with-lease origin main(永远别用--force)
⚠️ 容易踩的坑:--amend 漏掉 --no-edit 会打开编辑器让你改 message;用 --reset-author 会覆盖成当前 git config 的值,不是你指定的邮箱。
全量替换所有历史中的邮箱:必须用 git filter-repo
git filter-branch 在 Git 2.22+ 已标为 deprecated,它慢、难调试、会丢合并提交、破坏 GPG 签名。而 git filter-repo 是官方唯一推荐替代方案,速度快、语义明确、默认保留标签和 refs。
- 先安装:
pip install git-filter-repo(确保 Python ≥ 3.7) - 立刻备份分支:
git branch backup-before-filter(这步不能跳) - 准备
.mailmap文件,内容格式为:Correct Name <correct> Bad Name <bad></bad></correct> - 执行替换:
git filter-repo --mailmap .mailmap - 运行后所有 commit hash 都会变,本地分支指针失效,必须重建:
git checkout -B main - 同步到远程:
git push --force-with-lease --all && git push --force-with-lease --tags
⚠️ 注意:filter-repo 不识别 .git/config 中的 user 设置,只认 --mailmap 或命令行参数;若只想改 author 不动 committer,得用 --mailmap + 显式映射,不能依赖环境变量。
为什么不能直接改 git config?
git config --global user.email 只影响后续新提交,对已存在的 commit 完全无效——因为每个 commit 都固化了 author 和 committer 字段,它们是对象的一部分,不是配置项。
- 查看某个旧 commit 的真实作者信息,用:
git show -s --format="%an %ae | %cn %ce" <commit-hash></commit-hash> - 误以为改了 config 就等于改了历史,是新手最常犯的认知错误
- 如果只是想让下次提交不出错,那
git config --local user.email覆盖当前仓库即可
真正麻烦的是:一旦 commit 被推送到共享远程,修改它就不再是“本地操作”,而是“重写他人已拉取的历史”。哪怕只改一个邮箱,也得所有人重新 fetch + reset,这点经常被忽略。











