如何在 Git 中更改多次提交的作者和提交者姓名和电子邮件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/750172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:20:22  来源:igfitidea点击:

How to change the author and committer name and e-mail of multiple commits in Git?

gitversion-controlgit-filter-branchgit-rewrite-history

提问by Flávio Amieiro

I was writing a simple script in the school computer, and committing the changes to Git (in a repo that was in my pendrive, cloned from my computer at home). After several commits I realized I was committing stuff as the root user.

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

Is there any way to change the author of these commits to my name?

有什么方法可以将这些提交的作者更改为我的名字吗?

采纳答案by Pat Notz

Changing the author (or committer) would require re-writing all of the history. If you're okay with that and think it's worth it then you should check out git filter-branch. The man page includes several examples to get you started. Also note that you can use environment variables to change the name of the author, committer, dates, etc. -- see the "Environment Variables" section of the git man page.

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

Specifically, you can fix all the wrong author names and emails for all branches and tagswith this command (source: GitHub help):

具体来说,您可以使用此命令修复所有分支和标签的所有错误作者姓名和电子邮件(来源: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

回答by asmeurer

NOTE: This answer changes SHA1s, so take care on using it on a branch that has already been pushed. If you only want to fix the spelling of a name or update an old email, git lets you do this without rewriting history using .mailmap. See my other answer.

注意:此答案会更改 SHA1,因此请注意在已推送的分支上使用它。如果您只想修复名称的拼写或更新旧电子邮件,git 可以让您做到这一点,而无需使用.mailmap. 请参阅我的另一个答案

Using Interactive Rebase

使用交互式变基

You could do

你可以做

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

Then mark all of your bad commits as "edit" in the rebase file. If you also want to change your first commit, you have to manually add it as first line in the rebase file (follow the format of the other lines). Then, when git asks you to amend each commit, do

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

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

edit or just close the editor that opens, and then do

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

git rebase --continue

to continue the rebase.

继续rebase。

You could skip opening the editor altogether here by appending --no-editso that the command will be:

您可以通过追加来完全跳过在此处打开编辑器,--no-edit以便命令为:

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

Single Commit

单次提交

As some of the commenters have noted, if you just want to change the most recent commit, the rebase command is not necessary. Just do

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

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

This will change the author to the name specified, but the committer will be set to your configured user in git config user.nameand git config user.email. If you want to set the committer to something you specify, this will set both the author and the committer:

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

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

Note on Merge Commits

关于合并提交的说明

There was a slight flaw in my original response. If there are any merge commits between the current HEADand your <some HEAD before all your bad commits>, then git rebasewill flatten them (and by the way, if you use GitHub pull requests, there are going to be a ton of merge commits in your history). This can very often lead to very different history (as duplicate changes may be "rebased out"), and in the worst case, it can lead to git rebaseasking you to resolve difficult merge conflicts (which were likely already resolved in the merge commits). The solution is to use the -pflag to git rebase, which will preserve the merge structure of your history. The manpage for git rebasewarns that using -pand -ican lead to issues, but in the BUGSsection it says "Editing commits and rewording their commit messages should work fine."

我原来的回答有一点瑕疵。如果当前HEAD和您的之间有任何合并提交<some HEAD before all your bad commits>,那么git rebase会将它们展平(顺便说一下,如果您使用 GitHub 拉取请求,您的历史记录中将会有大量的合并提交)。这通常会导致非常不同的历史记录(因为重复的更改可能会被“重新定位”),在最坏的情况下,它可能会导致git rebase要求您解决困难的合并冲突(这些冲突可能已经在合并提交中解决了)。解决方案是使用-p标志 to git rebase,这将保留历史的合并结构。手册页git rebase警告说,使用-p-i可能会导致问题,但在BUGS它说“编辑提交和改写他们的提交消息应该可以正常工作。”

I've added -pto the above command. For the case where you're just changing the most recent commit, this is not an issue.

我已经添加-p到上面的命令中。对于您只是更改最近提交的情况,这不是问题。

回答by Rognon

You can also do:

你也可以这样做:

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

Note, if you are using this command in the Windows command prompt, then you need to use "instead of ':

请注意,如果您在 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

回答by Brian Gianforcaro

One liner, but be careful if you have a multi-user repository - this will change allcommits to have the same (new) author and committer.

一个班轮,但如果您有一个多用户存储库,请小心 - 这会将所有提交更改为具有相同的(新)作者和提交者。

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD

With linebreaks in the string (which is possible in bash):

在字符串中使用换行符(在 bash 中是可能的):

git filter-branch -f --env-filter "
    GIT_AUTHOR_NAME='Newname'
    GIT_AUTHOR_EMAIL='new@email'
    GIT_COMMITTER_NAME='Newname'
    GIT_COMMITTER_EMAIL='new@email'
  " HEAD

回答by lrkwz

It happens when you do not have a $HOME/.gitconfig initialized. You may fix this as:

当您没有初始化 $HOME/.gitconfig 时会发生这种情况。您可以将其修复为:

git config --global user.name "you name"
git config --global user.email [email protected]
git commit --amend --reset-author

tested with git version 1.7.5.4

使用 git 版本 1.7.5.4 测试

回答by blueyed

For a single commit:

对于单个提交:

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

(extracted from asmeurer's answer)

(摘自asmeurer的回答)

回答by Alex Brown

In the case where just the top few commits have bad authors, you can do this all inside git rebase -iusing the execcommand and the --amendcommit, as follows:

如果只有前几个提交的作者不好,您可以git rebase -i使用exec命令和--amend提交在内部执行所有操作,如下所示:

git rebase -i HEAD~6 # as required

which presents you with the editable list of commits:

它为您提供了可编辑的提交列表:

pick abcd Someone else's commit
pick defg my bad commit 1
pick 1234 my bad commit 2

Then add exec ... --author="..."lines after all lines with bad authors:

然后exec ... --author="..."在所有作者不好的行之后添加行:

pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name <[email protected]>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <[email protected]>" -C HEAD

save and exit editor (to run).

保存并退出编辑器(运行)。

This solution may be longer to type than some others, but it's highly controllable - I know exactly what commits it hits.

这个解决方案的输入时间可能比其他一些长,但它是高度可控的 - 我确切地知道它击中了什么提交。

Thanks to @asmeurer for the inspiration.

感谢@asmeurer 的启发。

回答by Olivier Verdier

Github has a nice solution, which is the following shell script:

Github 有一个很好的解决方案,它是以下 shell 脚本:

#!/bin/sh

git filter-branch --env-filter '

an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"

if [ "$GIT_COMMITTER_EMAIL" = "[email protected]" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]
then
    an="Your New Author Name"
    am="Your New Author Email"
fi

export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'

回答by svick

As docgnome mentioned, rewriting history is dangerous and will break other people's repositories.

正如 docgnome 所提到的,重写历史是危险的,并且会破坏其他人的存储库。

But if you really want to do that and you are in a bash environment (no problem in Linux, on Windows, you can use git bash, that is provided with the installation of git), use git filter-branch:

但是,如果您真的想这样做并且您处于 bash 环境中(在 Linux 中没问题,在 Windows 上,您可以使用 git bash,这是安装 git 时提供的),请使用git filter-branch

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL'

To speed things up, you can specify a range of revisions you want to rewrite:

为了加快速度,您可以指定要重写的修订范围:

git filter-branch --env-filter '
  if [ $GIT_AUTHOR_EMAIL = bad@email ];
    then GIT_AUTHOR_EMAIL=correct@email;
  fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD

回答by Ryanmt

When taking over an unmerged commit from another author, there is an easy way to handle this.

当从其他作者那里接管未合并的提交时,有一种简单的方法来处理这个问题。

git commit --amend --reset-author

git commit --amend --reset-author