如何更改多个提交的作者和提交者姓名/电子邮件

如何更改多个提交的作者和提交者姓名/电子邮件

技术背景

在使用Git进行版本控制时,有时会因为各种原因需要更改之前提交的作者和提交者姓名/电子邮件。例如,拼写错误、使用了临时邮箱等。但需要注意的是,更改提交信息会改变提交的SHA1值,因此在已经推送到远程仓库的分支上操作时要格外小心。

实现步骤

使用变基(Rebase)

  1. 配置Git全局信息:首先,你可能需要在git-config中修复你的姓名和邮箱。
1
2
git config --global user.name "New Author Name"
git config --global user.email "<[email protected]>"

这一步是可选的,但如果需要同时重置提交者姓名,这是一个好办法。

  1. 重写一系列提交的元数据:使用变基来重写一系列提交的元数据。
1
2
git rebase -r <some commit before all of your bad commits> \
--exec 'git commit --amend --no-edit --reset-author'

--exec 会在每次提交重写后运行 git commit 步骤。

  1. 更改根提交:如果你还想更改第一个提交(也称为“根”提交),需要在变基命令中添加 --root

  2. 仅更改作者信息:如果你不想更改配置,可以使用 --author "New Author Name <[email protected]>" 代替 --reset-author,但这样只会更新作者信息,不会更新提交者信息。

单个提交

如果你只想更改最近的一次提交,不需要进行变基操作,直接修改提交信息即可。

1
git commit --amend --no-edit --reset-author

整个项目历史

要更改整个项目历史的作者和提交者信息,可以使用以下命令。

1
git rebase -r --root --exec "git commit --amend --no-edit --reset-author"

旧版Git客户端(2020年7月之前)

对于旧版Git客户端,-r,--rebase-merges 可能不存在,可以使用 -p 代替,但 -p 存在严重问题,现已弃用。另外,可以使用 git filter-branch 来更改作者(或提交者)信息,但该命令存在诸多陷阱,不建议使用,建议使用替代工具 git filter-repo

使用 git filter-branch

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="[email protected]"
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

使用 git filter-repo

首先安装 git filter-repo,并根据 gitmailmap 格式创建一个 git-mailmap 文件。

1
Proper Name <[email protected]> Commit Name <[email protected]>

然后使用创建的邮件映射运行 filter-repo

1
git filter-repo --mailmap git-mailmap

核心代码

更改最近一次提交的作者信息

1
git commit --amend --author="Author Name <[email protected]>"

更改最后N次提交的作者信息

1
git rebase -i HEAD~N -x "git commit --amend --author 'Author Name <[email protected]>' --no-edit"

使用 git filter-repo 更改作者和提交者信息

1
2
3
4
5
6
7
8
9
10
11
12
13
git filter-repo --commit-callback '
old_email = b"[email protected]"
correct_name = b"Your Correct Name"
correct_email = b"[email protected]"

if commit.committer_email == old_email :
commit.committer_name = correct_name
commit.committer_email = correct_email

if commit.author_email == old_email :
commit.author_name = correct_name
commit.author_email = correct_email
'

最佳实践

  • 备份仓库:在进行任何历史重写操作之前,最好先备份仓库,以防数据丢失。
  • 使用 .mailmap:如果只是想修正姓名拼写或更新旧邮箱,而不想重写历史,可以使用 .mailmap 文件。
  • 小范围测试:在对整个项目历史进行更改之前,先在小范围的提交上进行测试,确保操作符合预期。

常见问题

临时目录已存在或 refs/original 引用已存在

如果在使用 git filter-branch 时遇到临时目录已存在或 refs/original 引用已存在的错误,可以添加 --force 标志来强制运行。

1
2
3
4
5
6
7
8
git filter-branch --force --env-filter '
if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
then
GIT_COMMITTER_NAME="<New name>";
GIT_COMMITTER_EMAIL="<New email>";
GIT_AUTHOR_NAME="<New name>";
GIT_AUTHOR_EMAIL="<New email>";
fi' -- --all

重写历史导致其他开发者仓库出现问题

重写历史会改变提交的SHA1值,可能会导致其他开发者的仓库出现问题。因此,在已经推送到远程仓库的分支上进行历史重写时要格外小心,最好与团队成员沟通协调。如果可能的话,尽量只在本地分支或未共享的分支上进行操作。


如何更改多个提交的作者和提交者姓名/电子邮件
https://119291.xyz/posts/2025-05-12.how-to-change-author-and-committer-info-for-multiple-commits/
作者
ww
发布于
2025年5月12日
许可协议