当我开始使用 git 时,我只是做了一个git init
并开始调用add
和commit
。现在我开始注意,我可以看到我的提交显示为,而不是我想要的地址。设置和cowens@localmachine
似乎会做我想要的事情,但我仍然有那些带有错误电子邮件地址/名称的旧提交。我该如何更正旧提交?GIT_AUTHOR_EMAIL
GIT_COMMITTER_EMAIL
答案1
只需调用一次 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 文档
答案2
Git 的 filter-branch 命令功能强大,但是对于任何重要的事情来说,它都非常难以使用,例如,如果您需要更正多个作者。
这是我发现有用的替代方案,它使用了 git-shortlog 手册页中描述的 .mailmap 功能。这提供了一种作者映射机制,我们可以将其与 git log 的格式化功能一起使用。我们可以使用它来生成命令来选择和修改命名的提交序列。
例如,假设您想要从提交 $START 开始更正分支 $BRANCH 上的作者身份。
您需要在存储库的顶级目录中创建一个 .mailmap 文件,将现有作者姓名映射到正确的作者姓名。您可以使用以下命令获取现有作者姓名列表:
git shortlog -se
您最终需要得到一个像这样的 .mailmap 文件(例如):
You <[email protected]> cowens@localmachine
You <[email protected]> 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 -
第一个命令从提交 $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" '
因此,当您需要更正作者时,您只需要生成一个 .mapfile 并执行以下操作:
git checkout -b $BRANCH2 $START
git reauthor $START..$BRANCH
可以将原始分支引用重新分配给新的分支,并删除新的分支:
git checkout $BRANCH
git reset --hard $BRANCH2 # be careful with this command
git branch -d $BRANCH2
答案3
### 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 [email protected]"
# (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 [email protected]"
# (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
答案4
按照 jedberg 的回答:您可以使用rebase -i
并选择编辑相关提交。如果您使用git commit --amend --author <AUTHOR DETAILS>
,那么git rebase continue
您可以浏览并修复历史记录。