在 git-filter-branch 的一次传递中重命名多个名称和电子邮件

Rename multiple names and emails in a single pass of git-filter-branch

是否可以一次 git filter-branch 批量重命名 2 个或更多电子邮件地址?

我尝试通过复制 if..fi clause:

来调整 this answer 中的代码
git filter-branch --commit-filter '
        if [ "$GIT_COMMITTER_NAME" = "<Old Name 1>" ];
        then
                GIT_COMMITTER_NAME="<New Name 1>";
                GIT_AUTHOR_NAME="<New Name 1>";
                GIT_COMMITTER_EMAIL="<New Email 1>";
                GIT_AUTHOR_EMAIL="<New Email 1>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi
        if [ "$GIT_COMMITTER_NAME" = "<Old Name 2>" ];
        then
                GIT_COMMITTER_NAME="<New Name 2>";
                GIT_AUTHOR_NAME="<New Name 2>";
                GIT_COMMITTER_EMAIL="<New Email 2>";
                GIT_AUTHOR_EMAIL="<New Email 2>";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD

但是它在过滤器分支期间给了我错误,看起来像这样:

error: duplicate parent bc8f9924c33558a275b8f694969529cf56232c80 ignored

然后分支历史就乱七八糟了:

在根据需要设置所有环境变量后,您只需要一个 git commit-tree 命令。例如,您的提交过滤器可能会读取如下内容:

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

(尽管如果要更改的名称数量越来越多,我可能会 运行 通过映射文件而不是一长串容易打错字的 if ... then,并且它分别映射作者和提交者可能更有意义)。

记住 filter-branch 简单地 复制 您告诉它复制的所有提交(通过使用 git commit-tree 制作新副本),同时构建一个 对的映射。这就是为什么进行两次提交并不好:一个现有的(旧的)SHA-1 现在必须映射到两个新的副本,这在 filter-branch 对提交图的处理方面是不允许的。 (多个旧的 SHA-1 可以映射到一个新的 SHA-1,如果你在复制过程中选择 省略 一些提交。也就是说,新图可以是双射或满射,但是 filter-branch 并不真正相信单射,因为它会尝试将旧引用映射到新图形。)