如何更改一系列提交的作者?


当前回答

我发现所提供的版本非常激进,特别是如果你从其他开发人员那里提交补丁,这将从本质上窃取他们的代码。

下面的版本确实适用于所有分支机构,并分别更改作者和发件人以防止这种情况发生。

感谢leif81的所有选择。

#!/bin/bash

git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "<old author>" ];
then
    GIT_AUTHOR_NAME="<new author>";
    GIT_AUTHOR_EMAIL="<youmail@somehost.ext>";
fi
if [ "$GIT_COMMITTER_NAME" = "<old committer>" ];
then
    GIT_COMMITTER_NAME="<new commiter>";
    GIT_COMMITTER_EMAIL="<youmail@somehost.ext>";
fi
' -- --all

其他回答

我也想添加我的示例。我想用给定的参数创建一个bash_function。

这在mint-linux 17.3中有效

# $1 => email to change, $2 => new_name, $3 => new E-Mail

function git_change_user_config_for_commit {

 # defaults
 WRONG_EMAIL=${1:-"you_wrong_mail@hello.world"}
 NEW_NAME=${2:-"your name"}
 NEW_EMAIL=${3:-"new_mail@hello.world"}

 git filter-branch -f --env-filter "
  if [ \$GIT_COMMITTER_EMAIL = '$WRONG_EMAIL' ]; then
    export GIT_COMMITTER_NAME='$NEW_NAME'
    export GIT_COMMITTER_EMAIL='$NEW_EMAIL'
  fi
  if [ \$GIT_AUTHOR_EMAIL = '$WRONG_EMAIL' ]; then
    export GIT_AUTHOR_NAME='$NEW_NAME'
    export GIT_AUTHOR_EMAIL='$NEW_EMAIL'
  fi
 " --tag-name-filter cat -- --branches --tags;
}

更改最后N次提交的作者的单个命令:

git rebase -i HEAD~N -x "git commit --amend --author 'Author Name <author.name@mail.example>' --no-edit"

笔记

用引用替换HEAD~N,直到您要重写提交的地方。这可以是哈希、HEAD~4、分支名称。。。--no edit标志确保gitcommit--modify不会要求额外的确认当您使用gitrebase-i时,您可以手动选择要更改作者的提交位置,

您编辑的文件将如下所示:

pick 897fe9e simplify code a little
exec git commit --amend --author 'Author Name <author.name@mail.example>' --no-edit
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <author.name@mail.example>' --no-edit
pick dc18f70 bugfix
exec git commit --amend --author 'Author Name <author.name@mail.example>' --no-edit

然后,您仍然可以修改一些行,以查看要更改作者的位置。这为您在自动化和控制之间提供了一个很好的中间地带:您可以看到将要运行的步骤,一旦您保存了所有内容,将立即应用。

请注意,如果您已经使用git-configuser.name<your_name>和git-config user.email<your_email>修复了作者信息,那么也可以使用以下命令:

git rebase -i HEAD~N -x "git commit --amend --reset-author --no-edit"

正如docgnome所提到的,重写历史是危险的,会破坏其他人的知识库。

但是,如果您真的想这样做,并且您处于bash环境中(在Linux和Windows中没有问题,您可以使用git bash,这是安装git时提供的),请使用gitfilter分支:

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

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

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

git过滤器分支的一个更安全的替代方案是git文档建议的过滤器回购工具。

git filter-repo --commit-callback '
  old_email = b"your-old-email@example.com"
  correct_name = b"Your Correct Name"
  correct_email = b"your-correct-email@example.com"
  
  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
  '

上述命令反映了此脚本中使用的逻辑,但使用过滤器repo而不是过滤器分支。

提交后回调选项的代码体基本上是用于处理提交的python代码。您可以在这里用python编写自己的逻辑。请在此处查看有关提交对象及其属性的更多信息。

由于filter repo工具未与git捆绑,您需要单独安装它。

请参阅先决条件和安装指南

如果您有一个python-env>=3.5,可以使用pip来安装它。

pip3 install git-filter-repo

注意:强烈建议在新克隆上尝试使用过滤器回购工具。操作完成后,也会移除遥控器。阅读更多有关为什么删除遥控器的信息。另请阅读INTERNALS部分中此工具的限制。

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

git rebase -i HEAD~6 # as required

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

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

然后添加exec--author=“…”在所有作者不好的行之后:

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

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

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

感谢@asmeurer的灵感。