Git,重写以前的提交用户名和电子邮件

JP *_*shy 134 git

我已经为Github上的一个项目提交了一堆提交,但是我意识到我没有在我正在使用的计算机上设置正确的电子邮件和提交者全名,因此用户的头像和电子邮件地址不在那里.

如何重写所有过去的提交电子邮件和用户名?

bra*_*obo 198

您可以添加此别名:

git config 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 "
Run Code Online (Sandbox Code Playgroud)

要更改作者姓名:

git change-commits GIT_AUTHOR_NAME "old name" "new name"
Run Code Online (Sandbox Code Playgroud)

或仅限最近10次提交的电子邮件:

git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" HEAD~10..HEAD
Run Code Online (Sandbox Code Playgroud)

别名:

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 "
Run Code Online (Sandbox Code Playgroud)

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

  • 固定为"eval:[[:找不到"在ubuntu上并添加一个确认`change-commits ="!f(){VAR1 = $ 1; VAR ='$'$ 1; OLD = $ 2; NEW = $ 3; echo \"你确定更换$ VAR $ OLD => $ NEW?(Y/N)\";读取OK;如果[\"$ OK \"='Y'];然后转3; git filter-branch --env -filter \"if [\\\"$ {VAR} \\\"='$ OLD']; 然后导出$ VAR1 ='$ NEW'; echo'到$ NEW'; fi \"$ @; fi;}; f"` (17认同)
  • 另外`git change-提交GIT_COMMITTER_EMAIL"old@example.com""new@example.com"`来更改提交者电子邮件. (12认同)
  • git:'change-commits'不是git命令.见'git --help'.表示您尚未将别名添加到git配置中.例如git config -e (8认同)
  • 当我在 Windows 7 PowerShell 中执行此操作时,我收到有关无法识别的命令 `then` 和 `fi\" \$@; }; f "` 的严重错误。似乎在 Windows Bash 的 Git 中工作正常。 (5认同)
  • 这只是使用我想更改的电子邮件复制了所有提交。似乎没有改写历史。@Olivier Verdier 的解决方案对我有用。 (4认同)
  • 我对“无法创建新备份...”问题的解决方案来自 https://blog.tinned-software.net/rewrite-author-of-entire-git-repository/ :“$ git fetch origin $ git Reset --hard origin/master $ git for-each-ref --format='删除 %(refname)' refs/original | --hard origin/master $ git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin $ git reflog expire --expire=now --all $ git gc --prune=now` 片段:https://gist.github.com/gwpl/dbf993223c8433767c81925513bef656 (3认同)
  • Git 还会创建备份。我用它来更改“GIT_COMMITTER_EMAIL”,效果很好。然而,当我尝试再次使用它来更改“GIT_AUTHOR_EMAIL”时,Git 抱怨并说“无法创建新的备份。”“先前的备份已存在于 refs/original/”“使用 -f 强制覆盖备份”。现在,我可以使用 `-f` 标志,或者可以使用 [`git update-ref -d refs/original/refs/heads/<branch-name>`](https://stackoverflow.com /a/34177510/1070480)。 (2认同)
  • 是否可以修改此别名以支持正则表达式匹配,以便可以匹配多个旧变量值?例如,如果我为各种提交使用了许多不同的电子邮件地址,并且我想将它们全部更改为新的? (2认同)
  • 我最终只是在GIT_AUTHOR_EMAIL GIT_COMMITTER_EMAIL中使用了`git checkout -b temp-branch`后跟`for var;在email @ address1 email @ address2 email @ address3中处理电子邮件;做git change-commits $ var $ email target-email @ address; git update-ref -d refs / original / refs / heads / temp-branch; 完成 “完成”更改作者和提交者的所有电子邮件地址。 (2认同)
  • 使用不同的输入连续执行两次会导致:`无法创建新备份。refs / original /`中已经存在先前的备份。 (2认同)
  • 您的 git 备份只是“.git/refs/original”中存在的可以删除的文件。 (2认同)
  • `git: 'change-commits' 不是 git 命令。请参阅“git --help”。 (2认同)
  • @qxo 的解决方案使用命令行而不是 .gitconfig: `git config --global alias.change-commits '!'"f() { VAR1=\$1; VAR='\$'\$1; OLD=\ $2; NEW=\$3; echo \"您确定要替换 \$VAR \$OLD => \$NEW 吗?(Y/N)\";read OK;if [ \"\$OK\" = 'Y ' ] ; 然后shift 3; git filter-branch --env-filter \"if [ \\\"\${VAR}\\\" = '\$OLD' ]; 然后导出 \$VAR1='\$NEW';echo 'to \$NEW'; fi\" \$@; fi;}; f "` (2认同)

Oli*_*ier 86

解决方案已经存在:在Git中更改多个提交的作者和提交者名称以及电子邮件

也就是说,

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD
Run Code Online (Sandbox Code Playgroud)

  • 请将问题标记为重复,而不是复制粘贴答案. (6认同)
  • 这不会改变分支的所有提交(整个历史)的作者姓名吗? (4认同)
  • 我运行了这个命令,现在我的存储库不会推送到 git 服务器或从 git 服务器拉取。 (3认同)
  • 是的,这将改变所有提交给新作者信息的提交. (2认同)
  • 如果我没有指定旧名称或旧电子邮件怎么办?git说"空身份<>不允许" (2认同)
  • 我认为这是最好的答案。获得最多支持的答案对我不起作用(它出错了,但我现在不记得错误了)。 (2认同)

ewa*_*all 35

如果您已经将一些提交推送到公共存储库,那么您希望这样做,或者它将创建其他人可能已使用的主服务器历史记录的备用版本."不要越过溪流......这会很糟糕......"

也就是说,如果它只是你对本地存储库的提交,那么在你推送到服务器之前,一定要解决这个问题.您可以使用git filter-branch带有该--commit-filter选项的命令,因此它只编辑与您的错误信息匹配的提交,如下所示:

git filter-branch --commit-filter '
      if [ "$GIT_AUTHOR_EMAIL" = "wrong_email@wrong_host.local" ];
      then
              GIT_AUTHOR_NAME="Your Name Here (In Lights)";
              GIT_AUTHOR_EMAIL="correct_email@correct_host.com";
              git commit-tree "$@";
      else
              git commit-tree "$@";
      fi' HEAD
Run Code Online (Sandbox Code Playgroud)

  • 之后,人们可能想使用“git update-ref -d refs/original/refs/heads/master”清除备份,请参阅&lt;/sf/answers/535841631/&gt;。 (4认同)
  • 请参阅[有关 git filter-branch 的重要警告](https://git-scm.com/docs/git-filter-branch#_warning)。请参阅 [@Pugsley 的答案](/sf/answers/4225492351/)。 (4认同)
  • 这很完美,而绿色标记的答案却没有 (3认同)
  • 我尝试过这个,但现在所有的提交都是双倍的。我怎样才能把它恢复回来? (3认同)
  • 仅供参考:如果您有多个不正确的姓名/电子邮件,您可能需要多次运行此操作。如果发生这种情况,它会向您发出以下错误:`先前的备份已存在于 refs/original/` 在这种情况下,使用新电子邮件重新运行它,并在 --commit- 之前添加 `-f`筛选。请自行决定使用。通常,在不知道它在做什么的情况下执行“-f”是一件危险的事情。 (2认同)

Amr*_*per 17

首先更新用户名和电子邮件

在全局或当前存储库中更新它们

git config --global user.name "Name"
git config --global user.email "<name@email.com>"
Run Code Online (Sandbox Code Playgroud)

请注意,您可以在 .git/config 文件中更新它们,只需将此部分附加到您的信息即可

[user]
    name = new name
    email = new email
Run Code Online (Sandbox Code Playgroud)

然后运行此命令来更新所有以前的提交

git rebase -r --root --exec "git commit --amend --no-edit --reset-author"
Run Code Online (Sandbox Code Playgroud)

  • 该命令的缺点是它将每次提交的修改日期更改为“rebase”的系统时间。 (3认同)
  • 哎呀。说得太早了。如何让一系列提交发生这种情况? (2认同)

sar*_*sso 15

应用Olivier Verdier的答案后:

git filter-branch -f --env-filter \
"GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='newemail'; \
GIT_COMMITTER_NAME='committed-name'; GIT_COMMITTER_EMAIL='committed-email';" HEAD
Run Code Online (Sandbox Code Playgroud)

...在原始存储库中推送已更改的历史记录:

git push origin +yourbranch
Run Code Online (Sandbox Code Playgroud)

上面的命令(注意加号)强制重写原始仓库的历史记录.谨慎使用!

  • 这将重写所有提交 - 无论是谁创作它.谨慎使用. (9认同)
  • 我这样做了。有什么办法可以恢复这个状态吗?现在所有的提交都是我的...... (3认同)
  • 请参阅[有关 git filter-branch 的重要警告](https://git-scm.com/docs/git-filter-branch#_warning)。请参阅 [@Pugsley 的答案](/sf/answers/4225492351/)。 (2认同)

8da*_*day 11

考虑到使用的git-filter-branch没有希望的,做同样的事情在git的过滤器回购(您可能需要与第一次安装它pip install git-filter-repo):

git-filter-repo --name-callback 'return name.replace(b"OldName", b"NewName")' --email-callback 'return email.replace(b"old@email.com", b"new@email.com")'
Run Code Online (Sandbox Code Playgroud)

如果存储库是原始的,没有远程,则必须添加--force以强制重写。(您可能希望在执行此操作之前创建您的存储库的备份。)

如果您不想保留 refs(它们将显示在 Git GUI 的分支历史记录中),则必须添加--replace-refs delete-no-add.

有关更多高级功能,请参阅“姓名和电子邮件过滤”

PS 被盗并从/sf/answers/4171434991/改进。

  • 今天运行了这个,虽然它有效,但它消除了我的起源。所以我必须“git remote add origin git@github.com:foo-repo....”,并且还要同步我需要的远程“git push origin +dev” (2认同)
  • 由于**单引号未正确处理**,粘贴的命令在 Windows 命令提示符 (cmd.exe) 中运行失败。人们必须切换到 **Git Bash** 才能使其发挥作用。参考:https://github.com/newren/git-filter-repo/issues/435 (2认同)

Nic*_*nia 9

对于那些只想要简单复制粘贴版本的人(除了更新电子邮件和姓名):

git config 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 "
git change-commits GIT_AUTHOR_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_AUTHOR_EMAIL <old@email.com> <new@email.com> -f
git change-commits GIT_COMMITTER_NAME "<Old Name>" "<New Name>" -f
git change-commits GIT_COMMITTER_EMAIL <old@email.com> <new@email.com> -f
Run Code Online (Sandbox Code Playgroud)

  • -bash: !f: 事件未找到 (5认同)

par*_*ver 6

已经给出的答案是完整的。但你确定你需要这些吗?例如。我面临着类似的问题,但这里的答案对于这种情况来说太过分了。我的案例和解决方案描述如下:

假设您有两个电子邮件 ID,no_longer_want@gmail.com并且want@gmail.com. 之前的提交可能no_longer_want@gmail.com不是您想要的电子邮件 ID。在这种情况下,一种选择是简单地链接want@gmail.com到您的 GitHub 帐户。

怎么做?

在设置页面的电子邮件部分中找到添加电子邮件的选项。

在此输入图像描述

还是迷路了?

github 页面上提到的前三个步骤就足够了。

笔记:

  1. Github 支持单个 github 帐户使用多个电子邮件 ID。
  2. 由于您没有替换电子邮件 ID,而只是添加一个新电子邮件 ID,因此通过这两个电子邮件 ID 提交的内容都会链接到您的 Github 帐户。
  3. 没有必要want@gmail.com将其设置为主要电子邮件 ID。


小智 5

https://help.github.com/articles/changing-author-info/

#!/bin/sh

git filter-branch --env-filter '

OLD_EMAIL="oldEmail@xxx-MacBook-Pro.local"
CORRECT_NAME="yourName"
CORRECT_EMAIL="yourEmail"

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
Run Code Online (Sandbox Code Playgroud)

这完全对我有用。git push之后,请确保在git的Web门户上看到更新。如果提交仍未链接到我的帐户,则在提交旁边显示默认的缩略图图像,并且未反映在我的贡献时间轴图表上,请转到提交网址并在网址末尾附加.patch,然后验证名称和电子邮件是正确的。

  • 这是唯一重写所有分支的一个。 (2认同)

cin*_*ada 5

如果您主要关心本地存储库显示名称,则重写历史记录的另一种方法是.mailmap file,它基本上是名称和电子邮件的列表。例如,将其放入.mailmap存储库根目录的文件中:

Tamika Page <tamika@somejob.com>
Orlando Cervantes <orlando.cervantes@otherjob.com> Orlando Jackson <orlando.jackson@otherjob.com>
Jared Michael <jared.michael@gmail.com> <jared@desktop.(none)>
Run Code Online (Sandbox Code Playgroud)

将导致任何归因于tamkia@somejob.com显示为名称 Tamika Page 的提交(无论提交者名称如何)、归因于Orlando Jackson <orlando.jackson@otherjob.com>显示为 Orlando Cervantes 的提交以及<jared@desktop.(none)>归因于 的讨厌的提交jared.michael@gmail.com。有关完整详细信息,请查看此功能的git 文档- 因为它内置于 git 中,所以它应该适用于任何相当新的 git 客户端。

不过这里有一个很大的警告:虽然它在官方 git 客户端中已经得到支持很长一段时间了,但并不能保证对各种 git 实现(特别是大型 Web 接口)的支持 - 请参阅这个问题,其中关于GitHub是否尊重它的共识混合但似乎消极。不幸的是,我在GitHubGitLab上整理了快速测试存储库,但似乎都没有注意到.mailmap

正如@paradocslover 的回答中提到的,这些服务有自己的接口来执行类似的操作,但您必须为每个服务进行设置,并且它根本不会影响您的本地副本。因为.mailmap它是存储库的一部分,所以它可以在本地为任何克隆你的存储库的人工作(你可以克隆上面链接的存储库来亲自查看),但它似乎不会显示在我测试的网络界面中。

当然,在某些情况下,您确实想要重写历史记录,但这可能相当具有侵入性,并且带有所有标准警告,因此对于某些情况,最好有这个选项,这可能就足够了,特别是如果重写不是实际的。

  • 它确实只是显示,实际提交数据保持不变。重写是一种更持久的解决方案,如果可以选择的话可能会更好。但对于某些用例来说,重写可能会造成很大的破坏(例如,如果存储库与大量人员共享),因此当重写不可能或不切实际时,这是一种替代方案。 (2认同)
  • 你的问题确实促使我实际检查大型网络客户端是否支持它,不幸的是,它似乎不支持,这很遗憾。他们有自己的处理方法,但如果他们使用现有的标准来这样做,那就太好了,尽管我认为他们对模仿的担忧可以通过他们自己的解决方案更好地解决,尽管即使他们自己的验证也只能解决一小部分这些问题的一部分。 (2认同)

归档时间:

查看次数:

49562 次

最近记录:

6 年,7 月 前