如何更改一系列提交的作者?
当前回答
正如docgnome所提到的,重写历史是危险的,会破坏其他人的知识库。
但是,如果您真的想这样做,并且您处于bash环境中(在Linux和Windows中没有问题,您可以使用git bash,这是安装git时提供的),请使用gitfilter分支:
git filter-branch --env-filter '
if [ $GIT_AUTHOR_EMAIL = bad@email ];
then GIT_AUTHOR_EMAIL=correct@email;
fi;
export GIT_AUTHOR_EMAIL'
要加快速度,可以指定要重写的修订范围:
git filter-branch --env-filter '
if [ $GIT_AUTHOR_EMAIL = bad@email ];
then GIT_AUTHOR_EMAIL=correct@email;
fi;
export GIT_AUTHOR_EMAIL' HEAD~20..HEAD
其他回答
我想对@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—强制原始主机
通过Amend更改提交作者姓名和电子邮件,然后用新提交替换旧提交:$git checkout<commit hash>#签出到需要修改的提交$gitcommit--modify--author“name”<author@email.com>“#更改作者姓名和电子邮件$git replace<旧提交哈希><新提交哈希>#用新提交替换旧提交$gitfilter分支--all#基于替换重写所有未来提交$git replace-d<old commit hash>#删除干净替换$git push-f origin HEAD#force push另一种方式回扣:$git rebase-i<good commit hash>#返回上一次提交#编辑器将打开,在提交更改作者之前将“pick”替换为“edit”$gitcommit--modify--author=“作者名称<author@email.com>“#更改作者姓名和电子邮件#保存更改并退出编辑器$git rebase--continue#完成rebase
我已经尝试了上面的脚本,但它不适合我,这解决了我的问题:
使用Git的“filter branch”命令。它允许您使用脚本批量处理(可能大量)提交。您可以在存储库中运行以下示例脚本(填写新旧电子邮件和名称的真实值):
git filter-branch --env-filter '
WRONG_EMAIL="wrong@example.com"
NEW_NAME="New Name Value"
NEW_EMAIL="correct@example.com"
if [ "$GIT_COMMITTER_EMAIL" = "$WRONG_EMAIL" ]
then
export GIT_COMMITTER_NAME="$NEW_NAME"
export GIT_COMMITTER_EMAIL="$NEW_EMAIL"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$WRONG_EMAIL" ]
then
export GIT_AUTHOR_NAME="$NEW_NAME"
export GIT_AUTHOR_EMAIL="$NEW_EMAIL"
fi
' --tag-name-filter cat -- --branches --tags
在此处查看更多详细信息
对于重置当前用户和当前时间戳的所有提交(包括首次提交):
git rebase --root --exec "git commit --amend --no-edit --date 'now' --reset-author"
试试看。它将执行与上述相同的操作,但以交互方式执行。
bash <(curl -s https://raw.githubusercontent.com/majdarbash/git-author-change-script/master/run.sh)
参考:https://github.com/majdarbash/git-author-change-script
推荐文章
- 为什么我需要显式地推一个新分支?
- 如何撤消最后的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之间的区别