协慌网

登录 贡献 社区

如何在 Git 中更改多个提交的作者和提交者名称以及电子邮件?

我正在学校的计算机上写一个简单的脚本,并将更改提交给 Git(在我的 pendrive 中的 repo 中,从我家里的计算机克隆)。经过几次提交,我意识到我是以 root 用户身份提交的东西。

有没有办法将这些提交的作者改成我的名字?

答案

使用 Interactive Rebase

你可以做到

git rebase -i -p <some HEAD before all of your bad commits>

然后将所有错误提交标记为 rebase 文件中的 “edit”。如果您还想更改第一次提交,则必须手动将其添加为 rebase 文件中的第一行(遵循其他行的格式)。然后,当 git 要求你修改每个提交时,做

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

编辑或只关闭打开的编辑器,然后执行

git rebase --continue

继续坚持。

你可以通过附加--no-edit跳过这里完全打开编辑器,这样命令将是:

git commit --amend --author "New Author Name <[email protected]>" --no-edit && \
git rebase --continue

单一提交

正如一些评论者所指出的,如果您只想更改最近的提交,则不需要 rebase 命令。做就是了

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

这会将作者更改为指定的名称,但是将在git config user.namegit config user.email中将提交者设置为已配置的用户。如果要将提交者设置为您指定的内容,则会设置作者和提交者:

git -c user.name="New Author Name" -c [email protected] commit --amend --reset-author

关于合并提交的注意事项

我最初的反应存在轻微缺陷。如果<some HEAD before all your bad commits>当前HEAD和你的<some HEAD before all your bad commits>之间存在任何合并提交,那么git rebase将使它们git rebase平(顺便说一下,如果你使用 GitHub pull 请求,那么将会有大量的合并承诺你的历史)。这通常会导致非常不同的历史记录(因为重复更改可能会 “重新出现”),并且在最坏的情况下,它可能会导致git rebase要求您解决困难的合并冲突(可能已在合并提交中解决) )。解决方案是使用-p标志来git rebase ,这将保留历史记录的合并结构。 git rebase的联机帮助页警告说使用-p-i会导致问题,但在BUGS部分中它说 “编辑提交和重写他们的提交消息应该可以正常工作”。

我在上面的命令中添加了-p 。对于刚刚更改最新提交的情况,这不是问题。

更改作者(或提交者)将需要重写所有历史记录。如果你对此感到满意并认为它值得,那么你应该看看git filter-branch 。手册页包含几个示例以帮助您入门。另请注意,您可以使用环境变量来更改作者,提交者,日期等的名称 - 请参阅git 手册页的 “环境变量” 部分。

具体来说,您可以使用此命令修复所有分支和标记的所有错误的作者姓名和电子邮件(来源: GitHub 帮助 ):

#!/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-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

注意,如果在 Windows 命令提示符下使用此命令,则需要使用"而不是'

git filter-branch --commit-filter "
        if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
        then
                GIT_COMMITTER_NAME="<New Name>";
                GIT_AUTHOR_NAME="<New Name>";
                GIT_COMMITTER_EMAIL="<New Email>";
                GIT_AUTHOR_EMAIL="<New Email>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi" HEAD