如何修改Git邮箱不丢失提交历史并关联GitHub贡献记录?
你可以完整保留所有提交历史,实现过往提交和GitHub账号的关联,根据你是否能接受重写提交历史,有两类可行方案:
零风险方案(无需修改任何提交历史)
这是最推荐的方案,完全不会影响仓库协作,不需要改动任何提交记录:
- 登录你的GitHub账号,进入账号设置的邮箱管理页面
- 把你之前通过
git config user.email配置的、未和账号绑定的旧提交邮箱,添加为账号的绑定邮箱 - 完成该邮箱的所有权验证
验证通过后GitHub会自动扫描全仓库的历史提交,所有使用该旧邮箱生成的提交都会自动关联到你的账号,贡献者列表展示、贡献度统计都会在数分钟内恢复正常,全程不会改动任何提交内容、历史时间线,对协作者完全无感知。
需重写历史的方案(适用于不想保留旧邮箱绑定的场景)
如果你不想把旧邮箱绑定到GitHub账号,可以通过修改历史提交信息的方式替换所有旧邮箱记录,注意:该操作会重写提交哈希,执行前必须提前同步所有仓库协作者,避免出现历史分叉冲突
1. 先修正后续提交的Git配置
先把未来新提交的身份信息改对,避免后续再出现匹配问题:
- 若要对本地所有仓库生效,执行全局配置:
git config --global user.name "你的GitHub公开显示用户名" git config --global user.email "你GitHub账号已绑定的有效邮箱"
- 若仅要对当前操作的私有仓库生效,在仓库根目录执行(去掉
--global参数即可):
git config user.name "你的GitHub公开显示用户名" git config user.email "你GitHub账号已绑定的有效邮箱"
如果你的GitHub账号开启了邮箱隐私保护,请填写GitHub分配给你的noreply格式专属邮箱,不要填写私人邮箱,否则会匹配失败。
2. 批量替换本地仓库历史中的旧邮箱
在仓库根目录执行如下脚本,提前把脚本里的旧邮箱、正确用户名、正确邮箱替换为你自己的实际信息:
git filter-branch --env-filter ' OLD_EMAIL="之前配置错误的未绑定旧邮箱" CORRECT_NAME="你的GitHub公开显示用户名" CORRECT_EMAIL="你GitHub账号已绑定的有效邮箱" 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
脚本执行完成后,所有历史提交的作者、提交者身份信息都会被替换为正确内容,提交内容、提交时间、分支结构、标签信息全部完整保留,不会丢失任何历史记录。
3. 推送修改后的历史到远程仓库
因为历史被重写,普通推送会被远程拒绝,需要执行强制推送覆盖远程旧历史:
git push --force --tags origin 'refs/heads/*'
强制推送会直接覆盖远程分支的现有历史,协作者在你推送完成后需要重新同步远程仓库,本地基于旧历史生成的未推送提交需要做变基适配,否则会出现历史冲突。
推送完成后等待5-10分钟,GitHub重新计算贡献统计后,你的账号就会正常显示在仓库贡献者列表中,所有历史提交都会关联到你的账号。
内容的提问来源于stack exchange,提问作者Francisco Shick

