如何在Git中更改多个提交的作者和提交者名称以及电子邮件?

时间:2009-04-15 03:09:24

标签: git version-control git-filter-branch git-rewrite-history

我正在学校的计算机上写一个简单的脚本,并将更改提交给Git(在我的pendrive中的repo中,从我家里的计算机克隆)。几次提交后,我意识到我是以root用户身份提交的东西。

有没有办法将这些提交的作者改成我的名字?

36 个答案:

答案 0 :(得分:1490)

使用Interactive Rebase

你可以做到

git rebase -i -p <some HEAD before all of your bad commits>

然后将所有错误提交标记为rebase文件中的“edit”。如果您还想更改第一次提交,则必须手动将其添加为rebase文件中的第一行(遵循其他行的格式)。然后,当git要求您修改每个提交时,请执行

 git commit --amend --author "New Author Name <email@address.com>" 

编辑或关闭打开的编辑器,然后执行

git rebase --continue

继续改变。

您可以通过附加--no-edit跳过此处完全打开编辑器 这样命令就是:

git commit --amend --author "New Author Name <email@address.com>" --no-edit && \
git rebase --continue

单一提交

正如一些评论者所指出的,如果您只想更改最近的提交,则不需要rebase命令。只是做

 git commit --amend --author "New Author Name <email@address.com>"

这会将作者更改为指定的名称,但提交者将设置为git config user.namegit config user.email中已配置的用户。如果要将提交者设置为您指定的内容,则会设置作者和提交者:

 git -c user.name="New Author Name" -c user.email=email@address.com commit --amend --reset-author

关于合并提交的注意事项

我原来的回答有轻微的缺陷。如果当前HEAD和您的<some HEAD before all your bad commits>之间存在任何合并提交,那么git rebase会将它们展平(顺便说一句,如果您使用GitHub拉取请求,则会有一个大量的合并提交在你的历史中)。这通常会导致非常不同的历史记录(因为重复的更改可能会“重新出现”),而在最坏的情况下,它可能会导致git rebase要求您解决困难的合并冲突(可能已在合并提交)。解决方案是使用-p标记git rebase,这将保留历史记录的合并结构。 git rebase的联机帮助页警告说,使用-p-i会导致问题,但在BUGS部分中,它说“编辑提交并重新提交其提交消息应该可以正常工作。 “

我已将-p添加到上述命令中。对于刚刚更改最新提交的情况,这不是问题。

答案 1 :(得分:985)

更改作者(或提交者)需要重写所有历史记录。如果您对此感到满意并认为值得,那么您应该查看git filter-branch。手册页包含几个示例以帮助您入门。另请注意,您可以使用环境变量来更改作者姓名,提交者,日期等。 - 请参阅git man page的“环境变量”部分。

具体来说,您可以使用此命令修复所有错误的作者姓名和电子邮件所有分支和标签(来源:GitHub help):

#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_COMMITTER_NAME="$CORRECT_NAME"
    export GIT_COMMITTER_EMAIL="$CORRECT_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
    export GIT_AUTHOR_NAME="$CORRECT_NAME"
    export GIT_AUTHOR_EMAIL="$CORRECT_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags

答案 2 :(得分:577)

你也可以这样做:

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

答案 3 :(得分:513)

一个班轮,但如果您有一个多用户存储库,请小心 - 这将改变所有提交以拥有相同的(新)作者和提交者。

git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD

在字符串中使用换行符(在bash中可以使用):

git filter-branch -f --env-filter "
    GIT_AUTHOR_NAME='Newname'
    GIT_AUTHOR_EMAIL='new@email'
    GIT_COMMITTER_NAME='Newname'
    GIT_COMMITTER_EMAIL='new@email'
  " HEAD

答案 4 :(得分:212)

当您没有初始化$ HOME / .gitconfig时会发生这种情况。你可以解决这个问题:

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

使用git版本1.7.5.4进行测试

答案 5 :(得分:181)

单次提交:

git commit --amend --author="Author Name <email@address.com>"

(摘自asmeurer的答案)

答案 6 :(得分:167)

如果只有前几个提交有不好的作者,你可以使用git rebase -i命令和exec提交在--amend内完成所有操作,如下所示:

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.com>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD

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

这个解决方案可能比其他解决方案更长,但它具有高度可控性 - 我确切知道它所提交的内容。

感谢@asmeurer的灵感。

答案 7 :(得分:108)

Github有一个nice solution,它是以下shell脚本:

#!/bin/sh

git filter-branch --env-filter '

an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"

if [ "$GIT_COMMITTER_EMAIL" = "your@email.to.match" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "your@email.to.match" ]
then
    an="Your New Author Name"
    am="Your New Author Email"
fi

export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'

答案 8 :(得分:80)

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

但是如果你真的想这样做并且你处于bash环境中(在Windows上没有问题,你可以使用git bash,也就是git的安装),使用git filter-branch

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

答案 9 :(得分:47)

当接管另一位作者的未合并提交时,有一种简单的方法可以解决这个问题。

git commit --amend --reset-author

答案 10 :(得分:40)

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

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

希望它有用。

答案 11 :(得分:38)

这是@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

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

  1. 临时目录已存在
  2. refs / original 开始的Refs已经存在 (这意味着先前已在存储库中运行了另一个filter-branch,然后在 refs / original 处备份了原始分支引用)
  3. 如果您想在不考虑这些错误的情况下强行投放,请添加 --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代替,这意味着只过滤当前分支上的所有修订。然后在重写的分支中不存在任何标记(或其他引用)。

答案 12 :(得分:23)

  1. 运行git rebase -i <sha1 or ref of starting point>
  2. 使用edit(或e
  3. 标记您要更改的所有提交
  4. 循环以下两个命令,直到您处理完所有提交:

    git commit --amend --reuse-message=HEAD --author="New Author <new@author.email>" ; git rebase --continue

  5. 这将保留所有其他提交信息(包括日期)。 --reuse-message=HEAD选项阻止消息编辑器启动。

答案 13 :(得分:21)

我使用以下内容为整个存储库重写作者,包括标记和所有分支:

git filter-branch --tag-name-filter cat --env-filter "
  export GIT_AUTHOR_NAME='New name';
  export GIT_AUTHOR_EMAIL='New email'
" -- --all

然后,如MAN page of filter-branch中所述,删除由filter-branch备份的所有原始引用(这是破坏性的,先备份):

git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d

答案 14 :(得分:20)

我通过摄取简单的author-conv-file(格式与solution的格式相同)来调整此git-cvsimport。它的工作原理是在所有分支中更改author-conv-file中定义的所有用户。

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

即。样本author-conv-file

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

答案 15 :(得分:18)

我发现所提供的版本具有攻击性,特别是如果你从其他开发者那里提交补丁,这将基本上窃取他们的代码。

以下版本适用于所有分支,并分别更改作者和comitter以防止这种情况发生。

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

答案 16 :(得分:17)

  1. author name & email更改提交Amend,然后替换old-commit with new-one

    $ git checkout <commit-hash>                            # checkout to the commit need to modify  
    $ git commit --amend --author "name <author@email.com>" # change the author name and email
    
    $ git replace <old-commit-hash> <new-commit-hash>      # replace the old commit by new one
    $ git filter-branch -- --all                           # rewrite all futures commits based on the replacement                   
    
    $ git replace -d <old-commit-hash>     # remove the replacement for cleanliness 
    $ git push -f origin HEAD              # force push 
    
  2. 另一种方式Rebasing

    $ git rebase -i <good-commit-hash>      # back to last good commit
    
    # Editor would open, replace 'pick' with 'edit' before the commit want to change author
    
    $ git commit --amend --author="author name <author@email.com>"  # change the author name & email
    
    # Save changes and exit the editor
    
    $ git rebase --continue                # finish the rebase
    

答案 17 :(得分:15)

我应该指出,如果唯一的问题是作者/电子邮件与平常不同,这不是问题。正确的解决方法是在目录的基础创建一个名为.mailmap的文件,其中包含

Name you want <email you want> Name you don't want <email you don't want>

从那时起,像git shortlog这样的命令会认为这两个名字是相同的(除非你明确告诉他们不要)。有关详细信息,请参阅http://schacon.github.com/git/git-shortlog.html

这具有所有其他解决方案的优点,因为您不必重写历史记录,如果您有上游,这可能会导致问题,并且始终是意外丢失数据的好方法。

当然,如果你做了自己的事情并且它应该真的是其他人,并且你现在不介意重写历史记录,那么更改提交作者可能是归因目的的一个好主意(在这种情况下我直接你到我的另一个答案)。

答案 18 :(得分:9)

如果您是此存储库的唯一用户,则可以使用git filter-branchsvick wrote)或git fast-export / {{3来重写历史记录加上过滤器脚本(如git fast-import中引用的文章中所述)或交互式docgnome answer。但是其中任何一个都会改变第一次更改提交的修订;这对于任何基于他/她的分支预先重写的更改的人来说意味着麻烦。

RECOVERY

如果其他开发人员没有将他们的工作基于预重写版本,那么最简单的解决方案就是重新克隆(再次克隆)。

或者他们可以尝试git rebase --pull,如果他们的存储库没有任何更改,它会快进,或者在重写提交之后重新绑定他们的分支(我们希望避免合并,因为它会保持预先重写comits永远)。所有这一切都假设他们没有做过工作;使用git stash来隐藏更改。

如果其他开发者使用功能分支,和/或git pull --rebase不起作用,例如因为没有设置上游,所以他们必须在重写后提交rebase之前完成工作。例如,在获取新的更改(git fetch)之后,对于master基于/ origin/master分叉的分支,需要运行

$ git rebase --onto origin/master origin/master@{1} master

此处origin/master@{1}是预重写状态(在获取之前),请参阅rebase


替代解决方案是使用 refs / replace / 机制,自1.6.5版以来在Git中可用。在此解决方案中,您为具有错误电子邮件的提交提供替换;然后任何人在他们的 fetch = +refs/replace/*:refs/replace/*中的适当位置获取'替换'引用(类似于.git/config refspec)将会透明地获得替换,而那些不获取这些引用的人会看到旧的承诺。

程序如下:

  1. 查找所有提交错误电子邮件的提交,例如使用

    $ git log --author=user@wrong.email --all
    
  2. 对于每个错误的提交,创建一个替换提交,并将其添加到对象数据库

    $ git cat-file -p <ID of wrong commit> | 
      sed -e 's/user@wrong\.email/user@example.com/g' > tmp.txt
    $ git hash-object -t commit -w tmp.txt
    <ID of corrected commit>
    
  3. 现在您已经更正了对象数据库中的提交,您必须告诉git使用gitrevisions命令通过更正错误提交来自动且透明地替换错误提交:

    $ git replace <ID of wrong commit> <ID of corrected commit>
    
  4. 最后,列出所有替换以检查此过程是否成功

    $ git replace -l
    

    并检查是否有替换

    $ git log --author=user@wrong.email --all
    
  5. 你当然可以自动执行这个程序......好吧,除了使用没有(还)批处理模式的git replace之外,所以你必须使用shell循环,或者用手代替”

    未经过测试! YMMV。

    请注意,使用refs/replace/机制时可能会遇到一些粗糙的问题:它是新的,尚未经过充分测试

答案 19 :(得分:8)

假设您要更改最近N次提交的作者:

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

注释

  • --no-edit标志可确保git commit --amend不要求额外确认
  • 使用git rebase -i时,您可以手动选择更改作者的提交,

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

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

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

答案 20 :(得分:6)

如果您要修复的提交是最新的提交,只有其中几个,您可以使用git resetgit stash的组合在配置权限后再次提交它们姓名和电子邮件。

序列将是这样的(对于2次错误提交,没有挂起的更改):

git config user.name <good name>
git config user.email <good email>
git reset HEAD^
git stash
git reset HEAD^
git commit -a
git stash pop
git commit -a

答案 21 :(得分:5)

你的问题很常见。请参阅“Using Mailmap to Fix Authors List in Git

为了简单起见,我创建了一个脚本来简化流程:git-changemail

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

  • 更改当前分支上的作者匹配

    $ git changemail -a old@email.com -n newname -m new@email.com
    
  • 更改&lt; branch&gt;上的作者和提交者匹配项和&lt; branch2&gt;。将-f传递给filter-branch以允许重写备份

    $ git changemail -b old@email.com -n newname -m new@email.com -- -f &lt;branch> &lt;branch2>
    
  • 在repo上显示现有用户

    $ git changemail --show-both
    

顺便说一句,在进行更改后,使用以下代码清除filter-branch中的备份:git-backup-clean

答案 22 :(得分:5)

最快,最简单的方法是使用git rebase的--exec参数:

npm pretty

这将创建一个如下所示的待办事项列表:

git rebase -i -p --exec 'git commit --amend --reset-author --no-edit'

,这将全部自动执行,当您有数百次提交时,该功能就会生效。

答案 23 :(得分:5)

如果您使用带有EGit的Eclipse,那么有一个非常简单的解决方案 假设:您在本地分支“local_master_user_x”中提交,由于用户无效,无法将其推送到远程分支“master”。

  1. 签出远程分支'master'
  2. 选择'local_master_user_x'包含更改的项目/文件夹/文件
  3. 右键单击 - 替换为 - Branch - 'local_master_user_x'
  4. 再次提交这些更改,这次是正确的用户并进入本地分支“master”
  5. 推送到远程'主'

答案 24 :(得分:5)

我们今天遇到了一个问题,即作者姓名中的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

快速概述:将您的存储库签出到临时文件,签出所有远程分支,运行将重写历史记录的脚本,强制推送新状态,并告诉所有同事做一个rebase pull to get变化。

我们在OS X上运行它时遇到了麻烦,因为它在某些方面搞砸了提交消息中的行结尾,所以我们不得不在之后的Linux机器上重新运行它。

答案 25 :(得分:5)

请注意,git存储两个不同的电子邮件地址,一个用于提交者(提交更改的人),另一个用于 author < / em>(撰写变更的人)。

大多数地方都不会显示提交者信息,但您可以使用git log -1 --format=%cn,%ce(或使用show而不是log来查看提交者信息以指定特定提交。

虽然更改上次提交的作者就像git commit --amend --author "Author Name <email@example.com>"一样简单,但是没有单行或参数可以对提交者信息执行相同的操作。

解决方案是(暂时或不临时)更改您的用户信息,然后修改提交,这会将提交者更新为您当前的信息:

git config user.email my_other_email@example.com 
git commit --amend

答案 26 :(得分:5)

使用交互式rebase,您可以在每次要更改的提交后放置修改命令。例如:

pick a07cb86 Project tile template with full details and styling
x git commit --amend --reset-author -Chead

答案 27 :(得分:2)

如果您是此回购的唯一用户,或者您不关心可能为其他用户破坏回购,那么是。如果你已经推送了这些提交并且它们存在于其他地方可以访问它们的地方,那么不,除非你不关心打破其他人的回购。问题是通过更改这些提交,您将生成新的SHA,这将导致它们被视为不同的提交。当其他人试图引入这些已更改的提交时,历史记录会有所不同,并且kaboom。

此页面http://inputvalidation.blogspot.com/2008/08/how-to-change-git-commit-author.html介绍了如何执行此操作。 (我没有试过这个YMMV)

答案 28 :(得分:2)

git docs here所建议的filter-branch工具是git的filter-repo的更安全替代品。

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
  '

上面的命令反映了this脚本中使用的逻辑,但是使用filter-repo而不是filter-branch

commit-callback选项之后的代码主体基本上是用于处理提交的python代码。您可以在这里用python编写自己的逻辑。详细了解commit对象及其属性here

由于filter-repo工具未与git捆绑在一起,因此您需要单独安装。

请参见PrerequistiesInstallation Guide

如果您的python env> = 3.5,则可以使用pip进行安装。

pip3 install git-filter-repo

注意:强烈建议在全新克隆上尝试使用filter-repo工具。操作完成后,遥控器也将被移除。进一步了解为何删除遥控器here。另请在INTERNALS部分下阅读此工具的限制。

答案 29 :(得分:2)

如果您想(轻松地)更改当前分支的作者,则可以使用以下内容:

# update author for everything since origin/master
git rebase \
  -i origin/master \
  --exec 'git commit --amend --no-edit --author="Author Name <author.name@email.co.uk>"'

答案 30 :(得分:1)

试一试。它将与上面提到的相同,但是交互式。

bash <(curl -s  https://raw.githubusercontent.com/majdarbash/git-author-change-script/master/run.sh)

参考:https://github.com/majdarbash/git-author-change-script

答案 31 :(得分:1)

以上所有答案均重写了存储库的历史记录。 只要没有多个作者使用过要更改的名称,特别是如果存储库已共享并且提交很旧,我更喜欢使用https://git-scm.com/docs/git-shortlog中记录的.mailmap。 它允许将不正确的名称/电子邮件映射到正确的名称/电子邮件,而无需修改回购历史记录。您可以使用以下行:

Proper Name <proper@email.xx> <root@localhost>

答案 32 :(得分:0)

git rebase -i YOUR_FIRTS_COMMIT_SHA^

while true; do git commit --amend --author="Name Surname <email@example.com>" --no-edit && git rebase --continue; done

在rebase完成后按^ C#(循环将继续更新上次提交)

答案 33 :(得分:0)

对于Windows下的用户,您也可以使用git-rocket-filter工具。

来自the documentation

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

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

答案 34 :(得分:0)

我想对@Rognon答案进行修改。如果选择的答案或其他答案对您不起作用(在我的特定问题是这种情况),此答案只是另一种选择:

目标:您将在所有历史记录中使用正确的作者来修复一个或多个作者,并且您将获得干净的历史记录而没有重复的记录。此方法通过将“主”分支替换为“干净”分支(不使用合并/变基)来起作用

注意::使用“主”存储库的任何人都可能需要在推送之前再次签出(执行这些步骤之后),因为合并可能会失败。

我们将使用一个名为“ clean”的新分支来执行操作(假设您要修复“ master”):

git checkout -b clean

(确保您位于“干净”分支中:git branch

修改以下脚本(替换电子邮件地址和名称)。请注意,此脚本预期会有两个错误的电子邮件/作者(例如),因此,如果您只需要修复一个作者,则可以删除条件的第二部分或像这样保留它(因为它将被忽略,因为它将不会被执行) t匹配)。

执行脚本。

#/bin/bash

git filter-branch --force --commit-filter '
        if [ "$GIT_COMMITTER_EMAIL" = "wrong1@example.com" -o "$GIT_COMMITTER_EMAIL" = "wrong2@example.com" ];
        then
                export GIT_COMMITTER_NAME="John Doe";
                export GIT_AUTHOR_NAME="John Doe";
                export GIT_COMMITTER_EMAIL="correct@example.com";
                export GIT_AUTHOR_EMAIL="correct@example.com";
        fi;
        git commit-tree "$@"
' --tag-name-filter cat -- --all

它必须报告:Ref 'refs/heads/clean' was rewritten。如果报告“未更改”,则可能是脚本中输入的电子邮件是错误的。

确认历史记录已通过以下方式更正:git log

如果您使用的是 github / gitlab (推荐=安全):

  1. 在远程中创建“干净”分支:

git push --set-upstream origin clean

  1. 将“干净”分支设置为默认分支
  2. 删除“ master”(在执行此操作之前,请确保所有操作均符合预期)。
  3. 基于“ clean”分支创建一个新的分支“ master”。
  4. 确认一切都很好之后,您可以立即删除“ clean”分支(也可以将其重命名)。

如果不使用github / gitlab ,或者您更喜欢通过命令进行操作:

  1. 从本地删除master分支:

git branch -d master

  1. 重命名分支:

git branch -m clean master

  1. 按下它(确保您的“主人”不受保护)

git push --force origin master

答案 35 :(得分:-2)

这不是您问题的答案,而是您可以用来避免将来出现此问题的脚本。它利用自Git version 2.9以来可用的全局挂钩,根据您的目录

检查您的电子邮件配置
#!/bin/sh
PWD=`pwd`
if [[ $PWD == *"Ippon"* ]] # 1)
then
  EMAIL=$(git config user.email)
  if [[ $EMAIL == *"Work"* ]] # 2)
  then
    echo "";
  else
    echo "Email not configured to your Work email in the Work directory.";
    git config user.email "youremail@youremail.com"
    echo "Git email configuration has now been changed to \"$(git config user$
    echo "\nPlease run your command again..."
    echo ''
    exit 1
  fi;
elif [[ $PWD == *"Personal"* ]]
then
  EMAIL=$(git config user.email)
  if [[ $EMAIL == "youremail@youremail.com" ]]
  then
    echo "";
  else
    echo "Email is not configured to your personal account in the Personal di$
    git config user.email "youremail@youremail.com"
    echo "Git email configuration has now been changed to \"$(git config user$
    echo "\nPlease run your command again..."
    echo ''
    exit 1;
  fi;
fi; 

它会检查您当前的工作目录,然后验证您的git是否配置为正确的电子邮件。如果没有,它会自动更改。查看完整详情here