我已经在Github上提交了一堆提交到一个项目,但我意识到我没有在我目前用于提交的计算机上设置正确的电子邮件和提交者全名,因此用户的头像和电子邮件地址不存在。

我如何重写所有过去提交的电子邮件和用户名?


当前回答

在应用Olivier Verdier的答案后:

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

...要在原始存储库使用上推送更改的历史记录:

git push origin +yourbranch

上面的命令(注意加号)也会改写原始回购的历史。请谨慎使用!

再次,警告:这将使所有提交的Newname/newemail提交!这种情况是,您有一个回购,其中只有一个作者错误地使用了不同的身份,您希望修复它。

其他回答

对于那些只想要简单的复制粘贴版本(除了更新电子邮件和姓名):

git config alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f "
git change-commits GIT_AUTHOR_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_AUTHOR_EMAIL <old@email.com> <new@email.com> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <old@email.com> <new@email.com> -f

你可以添加这个别名:

git config --global alias.change-commits '!'"f() { VAR=\$1; OLD=\$2; NEW=\$3; shift 3; git filter-branch --env-filter \"if [[ \\\"\$\`echo \$VAR\`\\\" = '\$OLD' ]]; then export \$VAR='\$NEW'; fi\" \$@; }; f"

修改作者名称。

git change-commits GIT_AUTHOR_NAME "old name" "new name"

或者是最后10次提交的邮件:

git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" HEAD~10..HEAD

别名:

change-commits="!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"$`echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" \$@; }; f"

来源:https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig

在应用Olivier Verdier的答案后:

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD

...要在原始存储库使用上推送更改的历史记录:

git push origin +yourbranch

上面的命令(注意加号)也会改写原始回购的历史。请谨慎使用!

再次,警告:这将使所有提交的Newname/newemail提交!这种情况是,您有一个回购,其中只有一个作者错误地使用了不同的身份,您希望修复它。

如果您已经将一些提交推到公共存储库,则不希望这样做,否则它将生成其他人可能使用的主历史记录的替代版本。“不要过河……那就糟了……”

也就是说,如果只是提交到本地存储库,那么务必在推送到服务器之前修复这个问题。你可以使用git filter-branch命令和——commit-filter选项,这样它只编辑与你的错误信息匹配的提交,就像这样:

git filter-branch --commit-filter '
      if [ "$GIT_AUTHOR_EMAIL" = "wrong_email@wrong_host.local" ];
      then
              GIT_AUTHOR_NAME="Your Name Here (In Lights)";
              GIT_AUTHOR_EMAIL="correct_email@correct_host.com";
              git commit-tree "$@";
      else
              git commit-tree "$@";
      fi' HEAD

考虑到不需要使用git-filter-branch,在git-filter-repo中做同样的事情(你可能需要先用pip install git-filter-repo安装它):

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"old@email.com", b"new@email.com")'

如果存储库是原始的,w/o远程,您将不得不添加——force来强制重写。(在执行此操作之前,您可能需要创建回购的备份。)

如果你不想保留引用(它们会显示在Git GUI的分支历史中),你必须添加——replace-refs delete-no-add。

要了解更高级的功能,请参见“姓名和电子邮件过滤”。

附注:从https://stackoverflow.com/a/59591928/714907窃取并改进。