更改以前提交的 git 电子邮件

Posted

技术标签:

【中文标题】更改以前提交的 git 电子邮件【英文标题】:Change git email for previous commits 【发布时间】:2016-04-23 09:27:26 【问题描述】:

所以我读了很多关于如何更改以前提交的电子邮件地址的内容,但由于某种原因我的没有更新。

我确实喜欢使用我的本地电子邮件 (nameofMyComputer@kevin.local) 对我的私人仓库进行 40 次提交,这很糟糕,因为这封电子邮件与 github 没有关联(而且不可能)。

然后我记得我需要在之前设置 git.config,所以我做了:

 git config user.email "newemail@example.com"

并进行了测试提交,它运行良好。

有没有办法可以将我之前的所有提交还原到这封新电子邮件?

我在 SO Change the author and committer name and e-mail of multiple commits in Git 上阅读了这个问题并使用了这个

 git filter-branch -f --env-filter "                         
                    GIT_AUTHOR_EMAIL='kevin.cohen26@gmail.com'; 
                    GIT_COMMITTER_EMAIL='kevin.cohen26@gmail.com';
                    " 
                HEAD

但它不起作用......我仍然可以看到我之前提交的电子邮件,扩展名为 .patch 作为 .local 电子邮件地址

【问题讨论】:

我相信您将不得不重写您的分支的历史来更改电子邮件,这些电子邮件似乎与提交者的姓名一起出现。如果您可以接受,那么filter-branchgit rebase 应该可以解决问题。 How to amend several commits in Git to change author的可能重复 【参考方案1】:

您确实可以像这样一次完成多个提交:

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

我在this answer 中解决了这个问题。

【讨论】:

然后git push --force? 因为这会重写你的提交,是的。考虑使用git push --force-with-lease,以确保不会破坏同事的工作。 这正是我想要的。谢谢你:) 感谢克里斯·梅斯! :) 对于其他使用此功能的人,请确保将 HEAD~40 更改为您想要影响的提交数量。阅读更多git-scm.com/book/en/v2/Git-Tools-Rewriting-History 为我工作!谢谢!【参考方案2】:

正如您在问题中提到的(您找到的答案的链接),这确实是脚本。

注意:

filter-branch 正在执行 rebase(将重写分支的历史),这意味着拥有分支将不得不删除并再次签出。


脚本来源来自这里 - Git-Tools-Rewriting-History:

# Loop over all the commits and use the --commit-filter
# to change only the email addresses

git filter-branch --commit-filter '

    # check to see if the committer (email is the desired one)
    if [ "$GIT_COMMITTER_EMAIL" = "<Old Email>" ];
    then
            # Set the new desired name
            GIT_COMMITTER_NAME="<New Name>";
            GIT_AUTHOR_NAME="<New Name>";

            # Set the new desired email
            GIT_COMMITTER_EMAIL="<New Email>";
            GIT_AUTHOR_EMAIL="<New Email>";

            # (re) commit with the updated information
            git commit-tree "$@";
    else
            # No need to update so commit as is
            git commit-tree "$@";
    fi' 
HEAD

脚本的作用是什么?

它会遍历您的所有提交,一旦找到匹配项,它就会替换提交者的姓名和电子邮件。

【讨论】:

我这样做了,但是当我查看我过去的提交时,它仍然显示为我的本地电子邮件地址......有什么想法吗? 您在哪里看到您的电子邮件?在同一个分支上还是在不同的分支上? 同一个分支.. 出于某种原因,我这样做了,然后我推送了它发生的事情是它再次使用新电子邮件重复了我的所有提交,但是,仍然没有显示在贡献日历中这是这个问题的重点 我不明白发生了什么。可以提供截图吗?【参考方案3】:

这是一个基于 Chris Maes' answer 的版本,它仅将更改应用于具有匹配电子邮件地址的提交,并使用 rebase --root(从 gi​​t 1.7 开始)从您的历史记录开始写入。

如果您想选择特定的基本提交,您需要删除 --root,并使用您想要的 refspec。

function reauthor_all 
  if [[ "$#" -eq 0 ]]; then
    echo "Incorrect usage, no email given, usage is: $FUNCNAME <email>" 1>&2
    return 1
  fi

  local old_email="$1"

  # Based on
  # SO: https://***.com/a/34863275/9238801

  local new_email="$(git config --get user.email)"
  local new_name="$(git config --get user.name)"

  # get each commit's email address ( https://***.com/a/58635589/9238801 )
  # I've broken this up into two statements and concatenated
  # because I want to delay evaluation

  local command='[[ "$(git log -1 --pretty=format:'%ae')" =='
  command+=" '$old_email' ]] && git commit --amend --author '$new_name <$new_email>' --no-edit || true"


  git rebase -i --root -x "$command"

在我自己的仓库中使用:

reauthor_all "personal.email@gmail.com"
hint: Waiting for your editor to close the file... 
Press ENTER or type command to continue
Executing: [[ "$(git log -1 --pretty=format:%ae)" == 'personal.email@gmail.com' ]] && git commit --amend --author 'Matthew Strasiotto <39424834+matthewstrasiotto@users.noreply.github.com>' --no-edit || true
Executing: [[ "$(git log -1 --pretty=format:%ae)" == 'personal.email@gmail.com' ]] && git commit --amend --author 'Matthew Strasiotto <39424834+matthewstrasiotto@users.noreply.github.com>' --no-edit || true
[detached HEAD 1e281b5] First Message
...etc

当它最终看起来正确时,你需要强制推送,这会改变提交的 shas,所以这会导致一大堆其他问题。

【讨论】:

注意:我使用字符串连接来延迟对命令某些部分的评估,如输出所示。这感觉像是一个丑陋的 hack,但似乎是最便携的丑陋 hack - 新版本的 bash (>= 4.4) 似乎支持 $param@Q 延迟评估,但如果你在 OSX 上,你将从 3.2 开始, & 我找到了抽象手册 \` escaping into bash functions, but rebase -x 'function_in_bashrc'` 找不到 function_in_bashrc 的解决方案。我的意思是,也许没有不包含丑陋 hack 的 bash 脚本之类的东西 如果有人对延迟评估参数替换/shell扩展有更好的想法,请权衡 像魅力一样工作!

以上是关于更改以前提交的 git 电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

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

sh 在Git中更改多个提交的名称和电子邮件

更改 Git/GitHub 存储库的作者姓名和电子邮件,为所有提交保留时间戳

Git更改未推送提交的作者[重复]

在 Git 中更改电子邮件地址

GIT 以不同的用户身份提交,没有电子邮件/或只有电子邮件