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


当前回答

这是@Brian版本的更详细版本:

要更改作者和提交人,可以执行以下操作(在bash中可以使用换行符):

git filter-branch --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all

您可能会遇到以下错误之一:

临时目录已存在以Refs/original开头的引用已存在(这意味着先前在存储库上运行了另一个过滤器分支,然后在refs/original处备份原始分支引用)

如果要在出现这些错误的情况下强制运行,请添加--force标志:

git filter-branch --force --env-filter '
    if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
    then
        GIT_COMMITTER_NAME="<New name>";
        GIT_COMMITTER_EMAIL="<New email>";
        GIT_AUTHOR_NAME="<New name>";
        GIT_AUTHOR_EMAIL="<New email>";
    fi' -- --all

可能需要对--all选项做一点解释:它使过滤器分支可以处理所有引用(包括所有分支)的所有修订。例如,这意味着标记也被重写,并且在重写的分支上可见。

一个常见的“错误”是使用HEAD,这意味着只过滤当前分支上的所有修订。然后,重写的分支中不存在标记(或其他引用)。

其他回答

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

git config --global user.name "you name"
git config --global user.email you@domain.example
git commit --amend --reset-author

使用Git 1.7.5.4版进行测试。

注意,这只修复了最后一次提交。

您还可以执行以下操作:

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

正如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

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

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

感谢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

对于重置当前用户和当前时间戳的所有提交(包括首次提交):

git rebase --root --exec "git commit --amend --no-edit --date 'now' --reset-author"