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


当前回答

我改编了这个解决方案,它通过摄取一个简单的author conv文件(格式与git cvsimport相同)来工作。它通过在所有分支中更改author conv文件中定义的所有用户来工作。

我们将其与cvs2git结合使用,将存储库从cvs迁移到git。

即示例作者conv文件

john=John Doe <john.doe@hotmail.com>
jill=Jill Doe <jill.doe@hotmail.com>

脚本:

 #!/bin/bash

 export $authors_file=author-conv-file

 git filter-branch -f --env-filter '

 get_name () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=\(.*\) <.*>$/\1/"
 }

 get_email () {
     grep "^$1=" "$authors_file" |
     sed "s/^.*=.* <\(.*\)>$/\1/"
 }

 GIT_AUTHOR_NAME=$(get_name $GIT_COMMITTER_NAME) &&
     GIT_AUTHOR_EMAIL=$(get_email $GIT_COMMITTER_NAME) &&
     GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME &&
     GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL &&
     export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
     export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
 ' -- --all

其他回答

您可以将其用作别名,以便执行以下操作:

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

添加到~/.gitconfig:

[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 "

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

希望它有用。

我已经尝试了上面的脚本,但它不适合我,这解决了我的问题:

使用Git的“filter branch”命令。它允许您使用脚本批量处理(可能大量)提交。您可以在存储库中运行以下示例脚本(填写新旧电子邮件和名称的真实值):

git filter-branch --env-filter '
WRONG_EMAIL="wrong@example.com"
NEW_NAME="New Name Value"
NEW_EMAIL="correct@example.com"

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

在此处查看更多详细信息

对于windows下的用户,也可以使用git火箭过滤器工具。

根据文档:

更改提交作者姓名和电子邮件:

git-rocket-filter --branch TestBranch --commit-filter '
    if (commit.AuthorName.Contains("Jim")) {   
        commit.AuthorName = "Paul"; 
        commit.AuthorEmail = "paul@company.com"; 
    }

你的问题很普遍。请参阅“使用Mailmap修复Git中的作者列表”

为了简单起见,我创建了一个脚本来简化这个过程:gitchangemail

将该脚本放到路径上后,可以发出以下命令:

更改当前分支上的作者匹配$git changemail-aold@email.com-n新名称-mnew@email.com更改<branch>和<branch2>上的作者和提交者匹配。将-f传递到筛选器分支以允许重写备份$git changemail-bold@email.com-n新名称-mnew@email.com---f&lt;分支>&lt;分支2>显示回购中的现有用户$git changemail--显示两者

顺便说一下,在进行更改后,使用:gitbackupclean从过滤器分支中清除备份

我们今天遇到了一个问题,作者名中的UTF8字符在构建服务器上造成了麻烦,因此我们必须重写历史记录来纠正这个问题。所采取的步骤包括:

步骤1:按照此处的说明,更改所有未来提交的git用户名:https://help.github.com/articles/setting-your-username-in-git/

步骤2:运行以下bash脚本:

#!/bin/sh

REPO_URL=ssh://path/to/your.git
REPO_DIR=rewrite.tmp

# Clone the repository
git clone ${REPO_URL} ${REPO_DIR}

# Change to the cloned repository
cd ${REPO_DIR}

# Checkout all the remote branches as local tracking branches
git branch --list -r origin/* | cut -c10- | xargs -n1 git checkout

# Rewrite the history, use a system that will preseve the eol (or lack of in commit messages) - preferably Linux not OSX
git filter-branch --env-filter '
OLD_EMAIL="me@something.com"
CORRECT_NAME="New Me"

if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
fi
' --tag-name-filter cat -- --branches --tags

# Force push the rewritten branches + tags to the remote
git push -f

# Remove all knowledge that we did something
rm -rf ${REPO_DIR}

# Tell your colleagues to `git pull --rebase` on all their local remote tracking branches

快速概述:将存储库签出到临时文件,签出所有远程分支,运行将重写历史记录的脚本,强制推送新状态,并告诉所有同事重新启动数据库以获取更改。

我们在OS X上运行它时遇到了问题,因为它在提交消息中以某种方式打乱了行结尾,所以我们不得不在Linux机器上重新运行它。