关于版本控制:如何在Git中更改多个提交的作者和提交者的姓名和电子邮件?

How to change the author and committer name and e-mail of multiple commits in Git?

我在学校的计算机上写了一个简单的脚本,并将更改提交给了Git(在我的PenDrive中的一个repo中,从我家的计算机克隆而来)。几次提交之后,我意识到我是作为根用户提交东西的。

有没有办法改变这些承诺的作者的名字?


使用交互式钢筋网

你可以做到

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

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

1
 git commit --amend --author"New Author Name"

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

1
git rebase --continue

继续使用钢筋。

你可以跳过在这里全部打开编辑器的步骤,附加--no-edit。这样命令将是:

1
2
git commit --amend --author"New Author Name" --no-edit && \
git rebase --continue

单一提交

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

1
 git commit --amend --author"New Author Name"

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

1
 git -c user.name="New Author Name" -c [email protected] commit --amend --reset-author

合并提交注意事项

我最初的回答有一点瑕疵。如果当前的HEAD和您的之间有合并提交,那么git rebase将使它们变平(顺便说一下,如果您使用github pull请求,那么在您的历史中会有大量的合并提交)。这通常会导致非常不同的历史(因为重复的更改可能被"重新平衡"),在最坏的情况下,它会导致git rebase要求您解决困难的合并冲突(这些冲突可能已经在合并提交中解决)。解决方案是使用-p标志到git rebase,这将保留您历史的合并结构。git rebase的手册页警告说,使用-p-i可能会导致问题,但在BUGS部分,它说"编辑提交和重新编写提交消息应该很好。"

我在上面的命令中添加了-p。对于只更改最近提交的情况,这不是问题。


更改作者(或提交者)需要重新编写所有历史。如果你认为这是值得的,那么你应该检查一下Git过滤器分支。该手册页包含几个示例,可以帮助您开始学习。还要注意,您可以使用环境变量来更改作者、提交者、日期等的名称——请参见Git手册页的"环境变量"部分。

具体来说,您可以使用此命令修复所有分支和标记的所有错误作者名称和电子邮件(来源:github帮助):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/sh

git filter-branch --env-filter '
OLD_EMAIL="[email protected]"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="[email protected]"
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


您还可以执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
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命令提示符中使用此命令,则需要使用"而不是'

1
2
3
4
5
6
7
8
9
10
11
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


一行程序,但是如果您有一个多用户存储库,那么要小心——这将改变所有提交,使其拥有相同的(新的)作者和提交者。

1
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中可以使用):

1
2
3
4
5
6
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


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

1
2
3
git config --global user.name"you name"
git config --global user.email [email protected]
git commit --amend --reset-author

使用Git版本1.7.5.4测试


对于单个提交:

1
git commit --amend --author="Author Name"

(摘自Asmeurer的回答)


如果只有前几位提交的作者不好,那么可以使用exec命令和--amend提交在git rebase -i内执行所有操作,如下所示:

1
git rebase -i HEAD~6 # as required

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

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

然后在所有作者不好的行后加上exec ... --author="..."行:

1
2
3
4
5
pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name" -C HEAD

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

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

感谢@asmeurer的启发。


Github有一个很好的解决方案,它是以下shell脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/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" ="[email protected]" ]
then
    cn="Your New Committer Name"
    cm="Your New Committer Email"
fi
if ["$GIT_AUTHOR_EMAIL" ="[email protected]" ]
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"
'


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

但是,如果您真的想这样做,并且您在一个bash环境中(在Linux中没有问题,在Windows中,您可以使用git-bash,这是在安装git时提供的),请使用git filter branch:

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

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

1
2
3
4
5
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 commit --amend --reset-author


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

1
git change-commits GIT_AUTHOR_NAME"old name""new name"

或最后10次承诺:

1
git change-commits GIT_AUTHOR_EMAIL"[email protected]""[email protected]" HEAD~10..HEAD

添加到~/.gitconfig:

1
2
[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

希望它有用。


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

要更改作者和提交者,可以这样做(使用bash中可能出现的字符串中的换行符):

1
2
3
4
5
6
7
8
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已存在(这意味着以前在存储库上运行过另一个筛选分支,然后在refs/original上备份原始分支引用)
  • 如果要在出现这些错误的情况下强制运行,请添加--force标志:

    1
    2
    3
    4
    5
    6
    7
    8
    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选项做一点解释:它使过滤器分支可以处理所有refs(包括所有分支)上的所有修订。例如,这意味着标记也会被重写,并在重写的分支上可见。

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


  • 运行git rebase -i
  • Mark All承诺您希望使用edite进行更改。
  • 循环以下两个命令,直到处理完所有提交:

    git commit --amend --reuse-message=HEAD --author="New Author "git rebase --continue

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


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

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

    然后,如filter branch的手册页所述,删除filter-branch备份的所有原始引用(这是破坏性的,首先备份):

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


    我修改了这个解决方案,它通过摄取一个简单的author-conv-file(格式与git cvsimport相同)。它通过改变所有分支机构中author-conv-file中定义的所有用户来工作。

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

    即样品author-conv-file

    1
    2
    john=John Doe <[email protected]>
    jill=Jill Doe <[email protected]>

    剧本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     #!/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


    我发现所呈现的版本有攻击性,特别是如果您提交来自其他开发人员的补丁,这将从本质上窃取他们的代码。

    下面的版本对所有分支都有效,并分别更改作者和Comitter以防止这种情况发生。

    为所有选项向LeiF81致敬。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/bin/bash

    git filter-branch --env-filter '
    if ["$GIT_AUTHOR_NAME" ="" ];
    then
        GIT_AUTHOR_NAME="<new author>";
        GIT_AUTHOR_EMAIL="<[email protected]>";
    fi
    if ["$GIT_COMMITTER_NAME" ="" ];
    then
        GIT_COMMITTER_NAME="<new commiter>";
        GIT_COMMITTER_EMAIL="<[email protected]>";
    fi
    ' -- --all

  • Amend变更承诺author name & email,然后更换old-commit with new-one

    1
    2
    3
    4
    5
    6
    7
    8
    $ git checkout <commit-hash>                            # checkout to the commit need to modify  
    $ git commit --amend --author"name" # change the author name and email

    $ git replace  <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      # remove the replacement for cleanliness
    $ git push -f origin HEAD              # force push
  • 另一种方法是Rebasing

    1
    2
    3
    4
    5
    6
    7
    8
    9
    $ 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"  # change the author name & email

    # Save changes and exit the editor

    $ git rebase --continue                # finish the rebase

  • 我要指出的是,如果唯一的问题是作者/电子邮件与您通常使用的不同,那么这不是问题。正确的解决方法是在目录的基部创建一个名为.mailmap的文件,其中的行如下

    1
    Name you want  Name you don't want

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

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

    当然,如果你像你自己一样承诺了某件事情,而且它真的应该是另一个人,此时你不介意重写历史,那么改变提交作者可能是一个很好的归因方法(在这种情况下,我会把你引向我的另一个答案)。


    如果您是该存储库的唯一用户,则可以使用git filter-branch(如svick所写),或git fast-export/git fast-import加过滤脚本(如docgnome answer中引用的文章中所述)或交互式rebase来重写历史记录。但这两种方法中的任何一种都会从第一次更改提交开始更改修订;这意味着任何基于分支预重写的更改的人都会遇到麻烦。

    恢复

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

    或者,他们可以尝试git rebase --pull,如果他们的存储库中没有任何更改,这将快速前进,或者在重新编写的提交之上重新调整分支(我们希望避免合并,因为这样可以永远保留预重写Comits)。所有这些假设都假定他们没有完成工作;否则,使用git stash来存储更改。

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

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

    这里,origin/master@{1}是预重写状态(fetch之前),请参见gitreversions。

    另一种解决方案是使用refs/replace/mechanism,从1.6.5版开始就可以在git中使用。在这个解决方案中,您为有错误电子邮件的提交提供替换;然后任何获取"替换"引用的人(如fetch = +refs/replace/*:refs/replace/*refspec在其.git/config的适当位置)都将透明地获取替换,而那些不获取这些引用的人将看到旧的提交。

    程序是这样的:

  • 查找包含错误电子邮件的所有提交,例如使用

    1
    $ git log [email protected] --all
  • 对于每个错误的提交,创建一个替换提交,并将其添加到对象数据库中。

    1
    2
    3
    4
    $ git cat-file -p <ID of wrong commit> |
      sed -e 's/user@wrong\.email/[email protected]/g' > tmp.txt
    $ git hash-object -t commit -w tmp.txt
    <ID of corrected commit>
  • 既然已经在对象数据库中更正了提交,那么就必须告诉Git使用git replace命令自动、透明地将错误的提交替换为已更正的提交:

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

    1
    $ git replace -l

    检查是否更换

    1
    $ git log [email protected] --all
  • 当然,您可以自动化这个过程…好吧,除了使用没有(还没有)批处理模式的git replace,所以您必须使用shell循环,或者用手工替换。

    没有测试过!YMMV。

    注意,在使用refs/replace/机制时,可能会遇到一些困难:它是新的,还没有经过很好的测试。


    如果要修复的提交是最新的,并且只有两个,则可以在配置正确的名称和电子邮件之后,使用git resetgit stash的组合再次返回提交它们。

    顺序如下(对于2个错误提交,没有挂起的更改):

    1
    2
    3
    4
    5
    6
    7
    8
    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

    假设您要更改最后n个提交的作者:

    1
    git rebase -i HEAD~4 -x"git commit --amend --author 'Author Name ' --no-edit"

    笔记

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

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

    1
    2
    3
    4
    5
    6
    pick 897fe9e simplify code a little
    exec git commit --amend --author 'Author Name ' --no-edit
    pick abb60f9 add new feature
    exec git commit --amend --author 'Author Name ' --no-edit
    pick dc18f70 bugfix
    exec git commit --amend --author 'Author Name ' --no-edit

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


    如果您使用Eclipse和eGit,那么有一个非常简单的解决方案。假设:您在本地分支"本地主用户"x中进行了提交,由于用户无效,无法将其推送到远程分支"主用户"。

  • 签出远程分支"master"
  • 选择"本地主用户"包含更改的项目/文件夹/文件
  • 右键单击-替换为-分支-"本地u主u用户u x"
  • 再次提交这些更改,这次作为正确的用户提交到本地分支"master"
  • 推到远程"主控"

  • 你的问题很普遍。参见"使用mailmap修复Git中的作者列表"

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

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

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

      1
      $ git changemail -a [email protected] -n newname -m [email protected]
    • 更改上的作者和提交者匹配。将-f传递给filter branch以允许重写备份

      1
      $ git changemail -b [email protected] -n newname -m [email protected] -- -f &lt;branch> &lt;branch2>
    • 在回购上显示现有用户

      1
      $ git changemail --show-both

    另外,在进行更改之后,用:git backup clean从filter分支清除备份


    我们今天遇到了这样一个问题:作者名中的utf8字符在构建服务器上造成了问题,因此我们必须重写历史记录以更正此问题。所采取的步骤是:

    步骤1:根据下面的说明,为将来的所有提交更改您在Git中的用户名:https://help.github.com/articles/setting-your-username-in-github/

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #!/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="[email protected]"
    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

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

    我们在OSX上运行它时遇到了问题,因为它在提交消息中以某种方式破坏了行尾,所以我们不得不在之后的Linux机器上重新运行它。


    请注意,Git存储了两个不同的电子邮件地址,一个用于提交者(提交更改的人),另一个用于作者(编写更改的人)。

    提交者信息在大多数地方都没有显示,但是您可以通过git log -1 --format=%cn,%ce看到它(或者使用show而不是log来指定特定的提交)。

    虽然更改上一次提交的作者和git commit --amend --author"Author Name"一样简单,但是没有人会对提交者信息做同样的操作。

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

    1
    2
    git config user.email [email protected]
    git commit --amend


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

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


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

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

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

    1
    2
    3
    4
    5
    6
    7
    pick ef11092 Blah blah blah
    exec git commit --amend --reset-author --no-edit
    pick 52d6391 Blah bloh bloo
    exec git commit --amend --reset-author --no-edit
    pick 30ebbfe Blah bluh bleh
    exec git commit --amend --reset-author --no-edit
    ...

    这将自动工作,当您有数百个提交时,这将工作。


    如果您是该回购协议的唯一用户,或者您不关心是否可能破坏其他用户的回购协议,那么是的。如果你推动了这些承诺,并且它们存在于其他地方可以访问它们的地方,那么就不会,除非你不关心破坏其他人的回购。问题是,通过更改这些提交,您将生成新的SHA,这将使它们被视为不同的提交。当其他人试图拉入这些改变的承诺时,历史就不同了。

    本页http://inputvalidation.blogspot.com/2008/08/how-to-change-git-commit-author.html介绍了如何进行验证。(我没试过,所以YMMV)


    我还想添加我的示例。我想用给定的参数创建一个bash_函数。

    这在mint-linux-17.3中有效。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # $1 => email to change, $2 => new_name, $3 => new E-Mail

    function git_change_user_config_for_commit {

     # defaults
     WRONG_EMAIL=${1:-"[email protected]"}
     NEW_NAME=${2:-"your name"}
     NEW_EMAIL=${3:-"[email protected]"}

     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;
    }

    试试这个。它将和上面提到的一样,但是是交互的。

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

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


    1
    2
    3
    git rebase -i YOUR_FIRTS_COMMIT_SHA^

    while true; do git commit --amend --author="Name Surname" --no-edit && git rebase --continue; done

    完成钢筋网后按^C(循环将继续更新上一次提交)


    这不是你问题的答案,而是你将来可以用来避免这个问题的一个脚本。它利用自Git 2.9版以来可用的全局挂钩,根据您在以下位置的目录检查您的电子邮件配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #!/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"[email protected]"
        echo"Git email configuration has now been changed to "$(git config user$
        echo"
    Please run your command again..."
        echo ''
        exit 1
      fi;
    elif [[ $PWD == *"Personal"* ]]
    then
      EMAIL=$(git config user.email)
      if [[ $EMAIL =="[email protected]" ]]
      then
        echo"";
      else
        echo"Email is not configured to your personal account in the Personal di$
        git config user.email"[email protected]"
        echo"Git email configuration has now been changed to "$(git config user$
        echo"
    Please run your command again..."
        echo ''
        exit 1;
      fi;
    fi;

    它检查您当前的工作目录,然后验证您的git是否配置为正确的电子邮件。如果没有,它会自动更改。请参阅此处的完整详细信息。