如何更改一系列提交的作者?
当前回答
试试看。它将执行与上述相同的操作,但以交互方式执行。
bash <(curl -s https://raw.githubusercontent.com/majdarbash/git-author-change-script/master/run.sh)
参考:https://github.com/majdarbash/git-author-change-script
其他回答
这个答案使用gitfilter分支,文档现在给出了这个警告:gitfilter分支有太多的缺陷,可能会对预期的历史重写造成不明显的影响(而且由于它的性能非常糟糕,因此几乎没有时间调查这些问题)。这些安全和性能问题不能向后兼容地解决,因此不建议使用。请使用其他历史筛选工具,如git filter repo。如果您仍然需要使用git过滤器分支,请仔细阅读安全(和性能)以了解过滤器分支的地雷,然后尽可能小心地避免列出的危险。
更改作者(或提交人)需要重写所有历史。如果您对此感到满意,并认为这是值得的,那么您应该查看gitfilter分支。手册页面包括几个示例,可帮助您入门。还要注意,您可以使用环境变量来更改作者、提交人、日期等的名称——请参阅git手册页面的“环境变量”部分。
具体来说,您可以使用以下命令修复所有分支和标记的所有错误作者名称和电子邮件(来源:GitHub帮助):
#!/bin/sh
git filter-branch --env-filter '
OLD_EMAIL="your-old-email@example.com"
CORRECT_NAME="Your Correct Name"
CORRECT_EMAIL="your-correct-email@example.com"
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
对于使用替代历史过滤工具gitfilter repo,您可以首先安装它并根据gitmailmap的格式构造gitmailmap。
Proper Name <proper@email.xx> Commit Name <commit@email.xx>
然后使用创建的mailmap运行过滤器repo:
git filter-repo --mailmap git-mailmap
注意:这个答案会改变SHA1,所以在已经推送的分支上使用它时要小心。如果你只想修复一个名字的拼写或更新一封旧邮件,Git可以让你不用使用.mailmap重写历史。
使用回扣
首先,如果您还没有这样做,您可能需要在git-config中修复您的名称:
git config --global user.name "New Author Name"
git config --global user.email "<email@address.example>"
这是可选的,但它也将确保重置提交者名称,假设这是您所需要的。
要使用rebase重写一系列提交的元数据,请执行
git rebase -r <some commit before all of your bad commits> \
--exec 'git commit --amend --no-edit --reset-author'
--exec将在每次提交被重写后运行gitcommit步骤(就像您运行gitcommit&&gitrebase一样——重复继续)。
如果您还想更改第一次提交(也称为“root”提交),则必须在rebase调用中添加--root。
这将把提交人和作者都更改为user.name/user.email配置。如果不想更改该配置,可以使用--author“New author Name”<email@address.example>“而不是--reset-author。请注意,这样做不会更新提交者,只更新作者。
单次提交
如果您只想更改最近的提交,则无需重新设置基准。只需修改承诺:
git commit --amend --no-edit --reset-author
整个项目历史
git rebase -r --root --exec "git commit --amend --no-edit --reset-author"
对于较旧的Git客户端(2020年7月之前)
-r、 --您可能不存在重基合并。作为替换,可以使用-p。请注意,-p存在严重问题,现已弃用。
我想对@Rognon的回答进行修改。如果所选答案或其他答案不适用于您(在我的特定问题中就是这样),则此答案只是另一种选择:
目标:您将在所有历史记录中用正确的作者修复一个或多个作者,并且您将获得无重复的干净历史记录。此方法的工作原理是将“master”分支替换为“clean”分支(它不使用merge/rebase)
注意:任何使用“主”存储库的人都可能需要在推送之前再次签出(执行这些步骤后),因为合并可能会失败。
我们将使用一个名为“clean”的新分支来执行操作(假设您想修复“master”):
git checkout-b clean
(确保您处于“干净”分支:git分支)
修改以下脚本(替换电子邮件地址和名称)。请注意,此脚本需要两个错误的电子邮件/作者(例如),因此如果您只需要修复一个作者,则可以删除条件的第二部分或将其保持原样(因为它将被忽略,因为它不匹配)。
执行脚本。
#/bin/bash
git filter-branch --force --commit-filter '
if [ "$GIT_COMMITTER_EMAIL" = "wrong1@example.com" -o "$GIT_COMMITTER_EMAIL" = "wrong2@example.com" ];
then
export GIT_COMMITTER_NAME="John Doe";
export GIT_AUTHOR_NAME="John Doe";
export GIT_COMMITTER_EMAIL="correct@example.com";
export GIT_AUTHOR_EMAIL="correct@example.com";
fi;
git commit-tree "$@"
' --tag-name-filter cat -- --all
它必须报告:Ref'refs/heads/clean'被重写。如果报告“未更改”,则脚本中输入的电子邮件可能是错误的。
使用:git log确认历史已更正
如果您正在使用github/gitlab(建议=安全):
在remote中创建“clean”分支:
git push—设置上游原点清洁
将“clean”分支设置为默认分支删除“master”(在执行此操作之前,确保一切都符合预期)。基于“clean”分支创建一个新分支“master”。确认一切正常后,您可以立即删除“clean”分支(也可以重命名它)。
如果您没有使用github/gitlab,或者您更喜欢使用命令:
从本地删除主分支:
git分支-d主
重命名分支:
gitbranch-m清理主机
推它(确保你的“主人”没有受到保护)
git push—强制原始主机
如果只有前几次提交的作者不好,您可以使用exec命令和--modify commit在git rebase-i内部执行此操作,如下所示:
git rebase -i HEAD~6 # as required
它为您提供了可编辑的提交列表:
pick abcd Someone else's commit
pick defg my bad commit 1
pick 1234 my bad commit 2
然后添加exec--author=“…”在所有作者不好的行之后:
pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name <email@address.example>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <email@address.example>" -C HEAD
保存并退出编辑器(运行)。
这个解决方案可能比其他解决方案键入的时间更长,但它是高度可控的——我确切地知道它命中了什么提交。
感谢@asmeurer的灵感。
如果您是此回购协议的唯一用户,或者您不关心其他用户是否可能破坏回购协议,那么可以。如果你已经推送了这些提交,并且它们存在于其他地方可以访问它们,那么就不会,除非你不在乎破坏他人的转发。问题是通过更改这些提交,您将生成新的SHA,这将导致它们被视为不同的提交。当其他人试图加入这些更改的提交时,历史是不同的,令人兴奋。
本页http://inputvalidation.blogspot.com/2008/08/how-to-change-git-commit-author.html描述了如何做到这一点。(我还没有尝试过,所以YMMV)
推荐文章
- 为什么我需要显式地推一个新分支?
- 如何撤消最后的git添加?
- Rubymine:如何让Git忽略Rubymine创建的.idea文件
- Gitignore二进制文件,没有扩展名
- Git隐藏错误:Git隐藏弹出并最终与合并冲突
- 了解Git和GitHub的基础知识
- 没有。Git目录的Git克隆
- Git与Mercurial仓库的互操作性
- 忽略git中修改(但未提交)的文件?
- “git restore”命令是什么?“git restore”和“git reset”之间有什么区别?
- Git合并与强制覆盖
- Git拉另一个分支
- 在Bash命令提示符上添加git分支
- 如何更改Git日志日期格式
- git pull -rebase和git pull -ff-only之间的区别