Git提交记录换人指南:3种场景+避坑全解析

平时写代码有没有遇到过这种情况:刚提交完,发现用错账号了——公司项目用了个人邮箱,或者反过来。我就干过这事,提交完了才看到 git log 里邮箱是自己的 Gmail,尴尬得很。

Git 提交记录里的作者信息,一旦提交就写进历史了,改起来确实麻烦。但也不是不能改,今天就把几种场景的方法说清楚,遇到问题直接照抄命令就行。

先说几句注意事项,省得踩坑:

  • 改提交记录会生成新的 commit hash,相当于重写历史
  • 如果已经 push 到远程了,改完得强制推送,会覆盖远程历史
  • 团队协作的话,改之前一定要通知大家,让人家先备份一下

先看看当前提交是啥情况

改之前先确认一下现在的提交信息:

1
2
3
4
5
6
7
# 看最近5条提交的作者、邮箱
git log --pretty=format:"%h %an <%ae> %s" -5

# 看当前仓库的 git 配置
git config --list --local | grep user
# 看全局配置
git config --list --global | grep user

这样能快速定位要改的是哪条提交。

场景一:刚提交完,发现用错账号了(还没 push)

这是最常见的情况,刚 commit 完,还没 push,发现作者信息错了。这种情况最简单,一条命令搞定。

方法一:直接指定新作者

不用改配置,直接改这次提交:

1
2
# 换成你的名字和邮箱
git commit --amend --author="张三 <zhangsan@company.com>" --no-edit

--no-edit 的意思是不改提交信息,只改作者。

方法二:先改配置再同步

如果你要长期用新账号,可以先把配置改了:

1
2
3
4
5
6
7
8
9
10
# 只对当前仓库生效(推荐,不影响其他项目)
git config user.name "张三"
git config user.email "zhangsan@company.com"

# 如果所有项目都要用这个账号,加 --global
# git config --global user.name "张三"
# git config --global user.email "zhangsan@company.com"

# 然后把最近一次提交的作者更新一下
git commit --amend --reset-author --no-edit

改完再看 git log,作者信息已经变了。

场景二:之前某次提交写错了(还没 push)

错的不一定是最近一次,可能是之前某一条。这种情况要用交互式变基,精准定位那条提交。

假设要改最近 3 条提交里的某一条:

第一步:启动变基

1
2
# 查看最近3条提交
git rebase -i HEAD~3

第二步:标记要改的提交

执行后会弹出编辑器(默认 vim),显示类似这样的内容:

1
2
3
pick abc1234 第一次提交
pick def5678 第二次提交
pick ghi9012 第三次提交

每条前面是 pick,表示保留这条提交。把要改的那条前面的 pick 改成 edit(或者简写 e),然后保存退出(vim 里按 Esc,输入 :wq 回车)。

第三步:修改作者

Git 会停在你标记的那条提交上,提示你可以修改了:

1
git commit --amend --author="张三 <zhangsan@company.com>" --no-edit

第四步:继续变基

1
git rebase --continue

如果要改多条,会一条条停让你改,重复步骤三四就行。

如果变基过程中冲突了,先解决冲突,然后 git add .,再 git rebase --continue

场景三:批量改,仓库里好多提交都要换人

如果是离职员工的提交要统一改掉,或者换企业邮箱后要批量更新,一条条改太累了。这种情况用 git filter-branch 批量处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 把旧邮箱的所有提交都改成新的作者信息
git filter-branch --env-filter '
OLD_EMAIL="old@example.com"
CORRECT_NAME="张三"
CORRECT_EMAIL="zhangsan@company.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
' -f --tag-name-filter cat -- --branches --tags

参数说明:

  • --env-filter:通过环境变量过滤修改
  • -f:强制覆盖之前的备份
  • --tag-name-filter cat:同步更新标签
  • --branches --tags:处理所有分支和标签

更快的工具:git filter-repo

git filter-branch 处理大仓库比较慢,官方推荐用 git filter-repo

1
2
3
4
5
6
7
8
9
10
11
12
# 先安装
pip install git-filter-repo

# 批量替换
git filter-repo --commit-callback '
if commit.author_email == b"old@example.com":
commit.author_name = b"张三"
commit.author_email = b"zhangsan@company.com"
if commit.committer_email == b"old@example.com":
commit.committer_name = b"张三"
commit.committer_email = b"zhangsan@company.com"
'

已经 push 了怎么办?

前面说的都是没 push 的情况。如果已经 push 到远程了,改完本地历史后必须强制推送:

1
2
3
4
5
# 推单个分支
git push origin main --force

# 推所有分支(慎用)
git push origin --force --all

强制推送会覆盖远程历史,团队协作的话一定要提前通知,让人家先 git pull --rebase 同步一下。

验证一下改没改对

改完确认一下:

1
2
3
4
5
6
# 看最近几条提交
git log --pretty=format:"%h %an <%ae> %s" -5

# 对比本地和远程
git fetch origin
git log --oneline HEAD..origin/main

没输出就说明同步好了。

几个常见问题

Q: vim 编辑器不会用怎么办?

vim 操作:按 i 进入编辑模式,改完按 Esc,输入 :wq 回车保存退出。

想换成记事本的话:git config --global core.editor notepad

Q: 强制推送后同事拉代码报错?

让同事执行:git pull --rebase origin main,有冲突解决冲突,然后 git add .,再 git rebase --continue

Q: 改完 commit hash 变了?

正常的,hash 是根据提交内容、作者、时间算出来的,改了作者 hash 肯定变。不影响功能,让大家同步一下就行。

Q: 能只改名字不改邮箱吗?

可以:git commit --amend --author="新名字 <旧邮箱>" --no-edit

总结

改 Git 提交作者,记住几个场景:

  • 刚提交还没 push:git commit --amend,最简单
  • 之前某条提交要改:git rebase -i,精准定位
  • 批量改:git filter-branchgit filter-repo

核心原则:没 push 的随便改,push 过的要谨慎,改完记得通知团队成员同步。

以后再遇到用错账号的情况,照着上面的命令抄就行,不用慌。