如何更改一系列提交的作者?
当前回答
正如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
其他回答
我们今天遇到了一个问题,作者名中的UTF8字符在构建服务器上造成了麻烦,因此我们必须重写历史记录来纠正这个问题。所采取的步骤包括:
步骤1:按照此处的说明,更改所有未来提交的git用户名:https://help.github.com/articles/setting-your-username-in-git/
步骤2:运行以下bash脚本:
#!/bin/sh
REPO_URL=ssh://path/to/your.git
REPO_DIR=rewrite.tmp
# Clone the repository
git clone ${REPO_URL} ${REPO_DIR}
# Change to the cloned repository
cd ${REPO_DIR}
# Checkout all the remote branches as local tracking branches
git branch --list -r origin/* | cut -c10- | xargs -n1 git checkout
# Rewrite the history, use a system that will preseve the eol (or lack of in commit messages) - preferably Linux not OSX
git filter-branch --env-filter '
OLD_EMAIL="me@something.com"
CORRECT_NAME="New Me"
if [ "$GIT_COMMITTER_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_COMMITTER_NAME="$CORRECT_NAME"
fi
if [ "$GIT_AUTHOR_EMAIL" = "$OLD_EMAIL" ]
then
export GIT_AUTHOR_NAME="$CORRECT_NAME"
fi
' --tag-name-filter cat -- --branches --tags
# Force push the rewritten branches + tags to the remote
git push -f
# Remove all knowledge that we did something
rm -rf ${REPO_DIR}
# Tell your colleagues to `git pull --rebase` on all their local remote tracking branches
快速概述:将存储库签出到临时文件,签出所有远程分支,运行将重写历史记录的脚本,强制推送新状态,并告诉所有同事重新启动数据库以获取更改。
我们在OS X上运行它时遇到了问题,因为它在提交消息中以某种方式打乱了行结尾,所以我们不得不在Linux机器上重新运行它。
一行代码,但如果您有一个多用户存储库,请小心——这会将所有提交更改为具有相同的(新的)作者和提交人。
git filter-branch -f --env-filter "GIT_AUTHOR_NAME='Newname'; GIT_AUTHOR_EMAIL='new@email'; GIT_COMMITTER_NAME='Newname'; GIT_COMMITTER_EMAIL='new@email';" HEAD
字符串中有换行符(这在bash中是可能的):
git filter-branch -f --env-filter "
GIT_AUTHOR_NAME='Newname'
GIT_AUTHOR_EMAIL='new@email'
GIT_COMMITTER_NAME='Newname'
GIT_COMMITTER_EMAIL='new@email'
" HEAD
对于所有提交,我的解决方案:
git rebase -i --root -x "git commit --amend --author 'bedorlan <bedorlan@gmail.com>' --no-edit"
注意:这个答案会改变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存在严重问题,现已弃用。
GitHub最初有一个很好的解决方案(断开链接),它是以下shell脚本:
#!/bin/sh
git filter-branch --env-filter '
an="$GIT_AUTHOR_NAME"
am="$GIT_AUTHOR_EMAIL"
cn="$GIT_COMMITTER_NAME"
cm="$GIT_COMMITTER_EMAIL"
if [ "$GIT_COMMITTER_EMAIL" = "your@email.to.match.example" ]
then
cn="Your New Committer Name"
cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "your@email.to.match.example" ]
then
an="Your New Author Name"
am="Your New Author Email"
fi
export GIT_AUTHOR_NAME="$an"
export GIT_AUTHOR_EMAIL="$am"
export GIT_COMMITTER_NAME="$cn"
export GIT_COMMITTER_EMAIL="$cm"
'
推荐文章
- Bower: ENOGIT Git未安装或不在PATH中
- Bitbucket上的Git:总是要求密码,即使上传了我的公共SSH密钥
- Git别名-多个命令和参数
- 如何添加一个“打开git-bash这里…”上下文菜单到windows资源管理器?
- Mercurial初学者:最终实用指南
- 是否可以在Git中只提取一个文件?
- 当我做“git diff”的时候,我怎么能得到一个并排的diff ?
- 在git中如何将提交移动到暂存区?
- 如何缩小。git文件夹
- 如何在本地删除分支?
- 找到包含特定提交的合并提交
- Windows上Git文件的权限
- 如何从一个枝头摘到另一个枝头
- 如何获得在两次Git提交之间更改的所有文件的列表?
- 什么是跟踪分支?