题 如何编辑git的历史记录以更正错误的电子邮件地址/名称[关闭]


当我开始使用git时,我刚做了一个 git init 并开始打电话 add 和 commit。现在我开始关注,我可以看到我的提交显示为 cowens@localmachine而不是我想要的地址。看起来好像在设置 GIT_AUTHOR_EMAIL 和 GIT_COMMITTER_EMAIL 会做我想要的,但我仍然有那些错误的电子邮件地址/名称的旧提交。如何更正旧提交?


72
2018-05-26 20:56




对于我们未来的读者:关于使用的问题 git 出于与此类似的目的,请进行更好的询问 堆栈溢出。 - Michael Hampton♦
这是最接近的问题 在stackoverflow.com上。 - naught101


答案:


您只需调用一次git filter-branch即可返回并修复所有提交。这与rebase具有相同的效果,但您只需要执行一个命令来修复所有历史记录,而不是单独修复每个提交。

您可以使用此命令修复所有错误的电子邮件:

git filter-branch --env-filter '
    oldname="(old name)"
    oldemail="(old email)"
    newname="(new name)"
    newemail="(new email)"
    [ "$GIT_AUTHOR_EMAIL"="$oldemail" ] && GIT_AUTHOR_EMAIL="$newemail"
    [ "$GIT_COMMITTER_EMAIL"="$oldemail" ] && GIT_COMMITTER_EMAIL="$newemail"
    [ "$GIT_AUTHOR_NAME"="$oldname" ] && GIT_AUTHOR_NAME="$newname"
    [ "$GIT_COMMITTER_NAME"="$oldname" ] && GIT_COMMITTER_NAME="$newname"
    ' HEAD

更多信息可从以下网址获得 git docs


80
2018-05-27 17:51



好吧,git filter-branch --env-filter'export GIT_AUTHOR_EMAIL =“foo@example.com”; GIT_AUTHOR_NAME =“Foo”'更简单,谢谢。如果我可以更改它,这将是可接受的答案(看起来服务器故障存在错误)。 - Chas. Owens
请注意,导出行不应在等号的两边都有空格。即它们应该如下所示:export GIT_AUTHOR_EMAIL =“(正确的电子邮件)”; - Andy Balaam
现在,我将如何在Windows上执行此操作? - Carsten Schmitz
@Deckard:将脚本保存到文本文件(如fixcommits.sh),然后运行Git Bash并运行脚本。我把脚本文件放在我的仓库的根目录下,然后导航到Git Bash中的那个文件夹,然后用./fixcommits.sh运行脚本 - Avalanchis
附录1 这个命令格式对我不起作用,但如果/那么: if [ "$GIT_AUTHOR_EMAIL" = "$oldemail" ]; then GIT_AUTHOR_EMAIL="$newemail"; fi - Josh M.


Git的filter-branch命令很强大,但是对于任何非常重要的事情都是非常笨拙的,例如,如果你有多个作者需要纠正。

这是我发现有用的替代方法,它使用git-shortlog联机帮助页中描述的.mailmap功能。这提供了一个作者映射机制,我们可以使用它与git log的格式化工具。我们可以使用它来生成命令来选择和修改命名的提交序列。

例如,假设您要在分支$ BRANCH上更正作者身份,从提交$ START开始。

您需要在存储库的顶级目录中创建一个.mailmap文件,该文件将现有的作者名称映射到正确的名称。您可以使用以下命令获取现有作者姓名的列表:

git shortlog -se

你需要得到像这样的.mailmap文件(比如说):

You <you@somewhere.org>   cowens@localmachine
You <you@somewhere.org>   root@localmachine

现在,您可以使用git log的格式化功能生成将$ BRANCH重写为$ BRANCH2的命令。

git checkout -b $BRANCH2 $START
git log --reverse --pretty=format:"cherry-pick %H; commit --amend --author='%aN <%aE>' -C %H" $START..$BRANCH | sh - 

第一个命令从commit $ START创建一个新的空分支。对于$ START和$ BRANCH结束之间的每次提交,第二个命令会选择原始提交到当前分支$ BRANCH2的末尾,并修改它以正确设置作者。

这通常也适用 - 把它放在你的〜/ .gitconfig中:

[alias]
    # git reauthor $START..$END
    reauthor = !sh -c 'eval `git log --reverse --topo-order --pretty=format:\"git cherry-pick %H &&  git commit --amend -C %H --author=\\\"%aN <%aE>\\\" && \" $0 ` "echo success" '

因此,当您需要更正作者时,现在您需要生成.map文件并执行以下操作:

git checkout -b $BRANCH2 $START
git reauthor $START..$BRANCH

可以将原始分支ref重新分配给新分支,并删除新分支:

git checkout $BRANCH
git reset --hard $BRANCH2 # be careful with this command
git branch -d $BRANCH2

27
2017-07-29 10:54



这太棒了。如果我有更多的代表,我会向你致敬。谢谢 :) - pistache


结合答案 如何修复git中第一次提交的元信息?

### Fix the first commit ###    
# create a temporary tag for the root-most commit so we can reference it
git tag root `git rev-list HEAD | tail -1`
# check it out on its own temporary branch
git checkout -b new-root root
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# now you've changed the commit message, so checkout the original branch again
git checkout @{-1}
# and rebase it onto your new root commit
git rebase --onto new-root root
### Fix the rest of the commits ###
git rebase -i root
# edit the file to read "edit <commit number> for each entry
# amend the commit
git commit --amend --author "Foo foo@example.com"
# (or if you've set the proper git **config** values)
git commit --amend -C HEAD --reset-author
# move to the next commit
git rebase --continue    
# continue running the last two commands until you see
# Successfully rebased and updated refs/heads/master.
### Clean up ###
# nuke the temporary branch we created
git branch -d new-root
# nuke the temporary tag we created
git tag -d root

8
2018-05-27 16:45



让我走上正轨,但需要命令: stackoverflow.com/a/28536828/307 而不是--author用法 - Brett Veenstra


按照jedberg的回答:你可以使用 rebase -i 并选择编辑有问题的提交。如果你使用 git commit --amend --author <AUTHOR DETAILS> 然后 git rebase continue 你可以通过并修复历史。


4
2018-05-26 22:02