Flá*_*iro 2282 git version-control git-filter-branch git-rewrite-history
我正在学校的计算机上编写一个简单的脚本,并将更改提交给Git(在我的pendrive中的repo中,从我家里的计算机克隆).几次提交后,我意识到我正在以root用户身份提交东西.
有没有办法将这些提交的作者改成我的名字?
asm*_*rer 1539
你可以做到
git rebase -i -p <some HEAD before all of your bad commits>
Run Code Online (Sandbox Code Playgroud)
然后将所有错误提交标记为rebase文件中的"edit".如果您还想更改第一次提交,则必须手动将其添加为rebase文件中的第一行(遵循其他行的格式).然后,当git要求你修改每个提交时,做
git commit --amend --author "New Author Name <email@address.com>"
Run Code Online (Sandbox Code Playgroud)
编辑或只关闭打开的编辑器,然后执行
git rebase --continue
Run Code Online (Sandbox Code Playgroud)
继续坚持.
你可以通过追加跳过这里完全打开编辑器,.mailmap
这样命令将是:
git commit --amend --author "New Author Name <email@address.com>" --no-edit && \
git rebase --continue
Run Code Online (Sandbox Code Playgroud)
正如一些评论者所指出的,如果您只想更改最近的提交,则不需要rebase命令.做就是了
git commit --amend --author "New Author Name <email@address.com>"
Run Code Online (Sandbox Code Playgroud)
这会将作者更改为指定的名称,但是提交者将在--no-edit
和中设置为您配置的用户git config user.name
.如果要将提交者设置为您指定的内容,则会设置作者和提交者:
git -c user.name="New Author Name" -c user.email=email@address.com commit --amend --reset-author
Run Code Online (Sandbox Code Playgroud)
我原来的回答有一点点缺陷.如果在当前git config user.email
和你之间有任何合并提交HEAD
,那么<some HEAD before all your bad commits>
将展平它们(顺便说一句,如果你使用GitHub拉取请求,你的历史记录中将会有大量的合并提交).这通常会导致非常不同的历史记录(因为重复更改可能会"重新出现"),并且在最坏的情况下,它可能导致git rebase
要求您解决困难的合并冲突(可能已在合并提交中解决).解决方案是使用git rebase
标志来-p
保留历史记录的合并结构.该联机帮助页git rebase
警告说使用git rebase
并-p
可能导致问题,但在该-i
部分中它说"编辑提交和重写其提交消息应该可以正常工作".
我已添加BUGS
到上面的命令中.对于刚刚更改最新提交的情况,这不是问题.
Pat*_*otz 1099
更改作者(或提交者)将需要重写所有历史记录.如果您对此感到满意并认为它值得,那么您应该查看git filter-branch.手册页包含几个示例以帮助您入门.另请注意,您可以使用环境变量来更改作者,提交者,日期等的名称 - 请参阅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
Run Code Online (Sandbox Code Playgroud)
小智 585
你也可以这样做:
git filter-branch --commit-filter '
if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
then
GIT_COMMITTER_NAME="<New Name>";
GIT_AUTHOR_NAME="<New Name>";
GIT_COMMITTER_EMAIL="<New Email>";
GIT_AUTHOR_EMAIL="<New Email>";
git commit-tree "$@";
else
git commit-tree "$@";
fi' HEAD
Run Code Online (Sandbox Code Playgroud)
注意,如果在Windows命令提示符下使用此命令,则需要使用"
而不是'
:
git filter-branch --commit-filter "
if [ "$GIT_COMMITTER_NAME" = "<Old Name>" ];
then
GIT_COMMITTER_NAME="<New Name>";
GIT_AUTHOR_NAME="<New Name>";
GIT_COMMITTER_EMAIL="<New Email>";
GIT_AUTHOR_EMAIL="<New Email>";
git commit-tree "$@";
else
git commit-tree "$@";
fi" HEAD
Run Code Online (Sandbox Code Playgroud)
Bri*_*aro 531
一个班轮,但如果你有一个多用户存储库,要小心 - 这将改变所有提交以拥有相同(新)作者和提交者.
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
Run Code Online (Sandbox Code Playgroud)
使用字符串中的换行符(可以在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
Run Code Online (Sandbox Code Playgroud)
lrk*_*kwz 216
当您没有初始化$ HOME/.gitconfig时会发生这种情况.你可以解决这个问题:
git config --global user.name "you name"
git config --global user.email you@domain.com
git commit --amend --reset-author
Run Code Online (Sandbox Code Playgroud)
用git版本1.7.5.4测试
blu*_*yed 183
对于单个提交:
git commit --amend --author="Author Name <email@address.com>"
Run Code Online (Sandbox Code Playgroud)
(摘自asmeurer的回答)
Ale*_*own 172
如果只有前几个提交有不好的作者,你可以git rebase -i
使用exec
命令和--amend
提交完成所有这些,如下所示:
git rebase -i HEAD~6 # as required
Run Code Online (Sandbox Code Playgroud)
它为您提供了可编辑的提交列表:
pick abcd Someone else's commit
pick defg my bad commit 1
pick 1234 my bad commit 2
Run Code Online (Sandbox Code Playgroud)
然后exec ... --author="..."
在所有行与坏作者之后添加行:
pick abcd Someone else's commit
pick defg my bad commit 1
exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD
pick 1234 my bad commit 2
exec git commit --amend --author="New Author Name <email@address.com>" -C HEAD
Run Code Online (Sandbox Code Playgroud)
保存并退出编辑器(运行).
这个解决方案可能比其他解决方案更长,但它是高度可控的 - 我确切知道它所提交的提交内容.
感谢@asmeurer的灵感.
Oli*_*ier 110
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" ]
then
cn="Your New Committer Name"
cm="Your New Committer Email"
fi
if [ "$GIT_AUTHOR_EMAIL" = "your@email.to.match" ]
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"
'
Run Code Online (Sandbox Code Playgroud)
svi*_*ick 80
正如docgnome所提到的,重写历史是危险的,并将打破其他人的存储库.
但是如果你真的想这样做并且你处于bash环境中(在Linux上没有问题,在Windows上,你可以使用git bash,这是随git的安装提供的),请使用git filter-branch:
git filter-branch --env-filter '
if [ $GIT_AUTHOR_EMAIL = bad@email ];
then GIT_AUTHOR_EMAIL=correct@email;
fi;
export GIT_AUTHOR_EMAIL'
Run Code Online (Sandbox Code Playgroud)
为了加快速度,您可以指定要重写的一系列修订:
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
Run Code Online (Sandbox Code Playgroud)
Rya*_*nmt 48
当从另一位作者接管一个未合并的提交时,有一种简单的方法来处理它.
git commit --amend --reset-author
bra*_*obo 46
您可以将其用作别名,以便执行以下操作:
git change-commits GIT_AUTHOR_NAME "old name" "new name"
Run Code Online (Sandbox Code Playgroud)
或者最近10次提交:
git change-commits GIT_AUTHOR_EMAIL "old@email.com" "new@email.com" HEAD~10..HEAD
Run Code Online (Sandbox Code Playgroud)
添加到〜/ .gitconfig:
[alias]
change-commits = "!f() { VAR=$1; OLD=$2; NEW=$3; shift 3; git filter-branch --env-filter \"if [[ \\\"$`echo $VAR`\\\" = '$OLD' ]]; then export $VAR='$NEW'; fi\" $@; }; f "
Run Code Online (Sandbox Code Playgroud)
资料来源:https://github.com/brauliobo/gitconfig/blob/master/configs/.gitconfig
希望它有用.
sti*_*gkj 38
这是@Brian版本的更精细版本:
要更改作者和提交者,您可以执行此操作(在bash中可以使用字符串中的换行符):
git filter-branch --env-filter '
if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
then
GIT_COMMITTER_NAME="<New name>";
GIT_COMMITTER_EMAIL="<New email>";
GIT_AUTHOR_NAME="<New name>";
GIT_AUTHOR_EMAIL="<New email>";
fi' -- --all
Run Code Online (Sandbox Code Playgroud)
您可能会收到以下错误之一:
如果要在不考虑这些错误的情况下强制运行,请添加--force
标志:
git filter-branch --force --env-filter '
if [ "$GIT_COMMITTER_NAME" = "<Old name>" ];
then
GIT_COMMITTER_NAME="<New name>";
GIT_COMMITTER_EMAIL="<New email>";
GIT_AUTHOR_NAME="<New name>";
GIT_AUTHOR_EMAIL="<New email>";
fi' -- --all
Run Code Online (Sandbox Code Playgroud)
-- --all
可能需要对该选项进行一些解释:它使filter-branch适用于所有refs(包括所有分支)的所有修订.这意味着,例如,标签也被重写并在重写的分支上可见.
一个常见的"错误"是使用HEAD
,这意味着只过滤当前分支上的所有修订.然后在重写的分支中不存在标签(或其他引用).
小智 23
git rebase -i <sha1 or ref of starting point>
edit
(或e
)循环以下两个命令,直到您处理完所有提交:
git commit --amend --reuse-message=HEAD --author="New Author <new@author.email>"
;
git rebase --continue
这将保留所有其他提交信息(包括日期).该--reuse-message=HEAD
选项阻止消息编辑器启动.
Ton*_*vel 22
我使用以下内容为整个存储库重写作者,包括标记和所有分支:
git filter-branch --tag-name-filter cat --env-filter "
export GIT_AUTHOR_NAME='New name';
export GIT_AUTHOR_EMAIL='New email'
" -- --all
Run Code Online (Sandbox Code Playgroud)
然后,如过滤器分支的MAN页面中所述,删除所有备份的原始引用filter-branch
(这是破坏性的,先备份):
git for-each-ref --format="%(refname)" refs/original/ | \
xargs -n 1 git update-ref -d
Run Code Online (Sandbox Code Playgroud)
Lei*_*ldt 21
我改编了这个解决方案,通过摄取一个简单的author-conv-file
格式(格式与git-cvsimport的格式相同).它的工作原理是更改author-conv-file
所有分支中定义的所有用户.
我们结合使用cvs2git
它将我们的存储库从cvs迁移到git.
即样品 author-conv-file
john=John Doe <john.doe@hotmail.com>
jill=Jill Doe <jill.doe@hotmail.com>
Run Code Online (Sandbox Code Playgroud)
剧本:
#!/bin/bash
export $authors_file=author-conv-file
git filter-branch -f --env-filter '
get_name () {
grep "^$1=" "$authors_file" |
sed "s/^.*=\(.*\) <.*>$/\1/"
}
get_email () {
grep "^$1=" "$authors_file" |
sed "s/^.*=.* <\(.*\)>$/\1/"
}
GIT_AUTHOR_NAME=$(get_name $GIT_COMMITTER_NAME) &&
GIT_AUTHOR_EMAIL=$(get_email $GIT_COMMITTER_NAME) &&
GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME &&
GIT_COMMITTER_EMAIL=$GIT_AUTHOR_EMAIL &&
export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&
export GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL
' -- --all
Run Code Online (Sandbox Code Playgroud)
Chr*_*aes 21
一个用于更改最后N次提交的作者的命令:
git rebase -i HEAD~4 -x "git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit"
Run Code Online (Sandbox Code Playgroud)
笔记
--no-edit
标志可以确保git commit --amend
不要求额外的确认git rebase -i
,您可以手动选择更改作者的提交,您编辑的文件将如下所示:
pick 897fe9e simplify code a little
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick abb60f9 add new feature
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
pick dc18f70 bugfix
exec git commit --amend --author 'Author Name <author.name@mail.com>' --no-edit
Run Code Online (Sandbox Code Playgroud)
然后,您仍然可以修改一些行,以查看要在哪里更改作者。这为您提供了介于自动化和控制之间的良好中间立场:您将看到将要运行的步骤,一旦保存,所有内容将立即应用。
dra*_*hnr 18
我发现所提供的版本是积极的,特别是如果你从其他开发人员提交补丁,这将基本上窃取他们的代码.
下面的版本适用于所有分支,并分别更改作者和comitter以防止这种情况.
感谢leif81的所有选项.
#!/bin/bash
git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "<old author>" ];
then
GIT_AUTHOR_NAME="<new author>";
GIT_AUTHOR_EMAIL="<youmail@somehost.ext>";
fi
if [ "$GIT_COMMITTER_NAME" = "<old committer>" ];
then
GIT_COMMITTER_NAME="<new commiter>";
GIT_COMMITTER_EMAIL="<youmail@somehost.ext>";
fi
' -- --all
Run Code Online (Sandbox Code Playgroud)
Saj*_*han 18
更改承诺author name & email
的Amend
,然后替换old-commit with new-one
:
$ git checkout <commit-hash> # checkout to the commit need to modify
$ git commit --amend --author "name <author@email.com>" # change the author name and email
$ git replace <old-commit-hash> <new-commit-hash> # replace the old commit by new one
$ git filter-branch -- --all # rewrite all futures commits based on the replacement
$ git replace -d <old-commit-hash> # remove the replacement for cleanliness
$ git push -f origin HEAD # force push
Run Code Online (Sandbox Code Playgroud)另一种方式Rebasing
:
$ git rebase -i <good-commit-hash> # back to last good commit
# Editor would open, replace 'pick' with 'edit' before the commit want to change author
$ git commit --amend --author="author name <author@email.com>" # change the author name & email
# Save changes and exit the editor
$ git rebase --continue # finish the rebase
Run Code Online (Sandbox Code Playgroud)asm*_*rer 16
我应该指出,如果唯一的问题是作者/电子邮件与平常不同,这不是问题.正确的解决方法是创建一个.mailmap
在目录底部调用的文件,其中包含类似的行
Name you want <email you want> Name you don't want <email you don't want>
Run Code Online (Sandbox Code Playgroud)
从那时起,命令git shortlog
就会认为这两个名字是相同的(除非你明确告诉他们不要).有关更多信息,请参见http://schacon.github.com/git/git-shortlog.html.
这具有所有其他解决方案的优点,因为您不必重写历史记录,如果您有上游,这可能会导致问题,并且始终是意外丢失数据的好方法.
当然,如果你做了自己的事情并且应该真的是其他人,并且你现在不介意重写历史记录,那么更改提交作者可能是一个好主意用于归因目的(在这种情况下我指导你到我的这里的其他答案).
Sau*_*ari 14
一个更安全的 git 替代方法filter-branch
是filter-repo
git docs here建议的工具。
git filter-repo --commit-callback '
old_email = b"your-old-email@example.com"
correct_name = b"Your Correct Name"
correct_email = b"your-correct-email@example.com"
if commit.committer_email == old_email :
commit.committer_name = correct_name
commit.committer_email = correct_email
if commit.author_email == old_email :
commit.author_name = correct_name
commit.author_email = correct_email
'
Run Code Online (Sandbox Code Playgroud)
上述命令的反射镜中所用的逻辑这个脚本,但使用filter-repo
代替filter-branch
。
commit-callback
选项后的代码体基本上是用于处理提交的python代码。你可以在这里用python编写自己的逻辑。在此处查看有关commit
对象及其属性的更多信息。
由于filter-repo
工具未与 git 捆绑在一起,因此您需要单独安装它。
如果你有一个 python env >= 3.5,你可以用pip
它来安装它。
pip3 install git-filter-repo
Run Code Online (Sandbox Code Playgroud)
注意:强烈建议filter-repo
在新的克隆上尝试工具。操作完成后,遥控器也会被移除。在这里阅读更多关于为什么遥控器被删除的信息。另请阅读内部部分下此工具的限制。
如果您是此存储库的唯一用户,则可以使用(如svick编写)或/ plus过滤脚本(如docgnome answer中引用的文章中所述)或交互式rebase 重写历史记录.但是其中任何一个都会改变第一次更改提交后的修订; 对于任何基于他/她的分支预先重写的更改的人来说,这意味着麻烦.git filter-branch
git fast-export
git fast-import
复苏
如果其他开发人员没有将他们的工作基于预重写版本,那么最简单的解决方案就是重新克隆(再次克隆).
或者他们可以尝试git rebase --pull
,如果他们的存储库中没有任何更改,它会快进,或者在重写提交之后重新绑定他们的分支(我们希望避免合并,因为它将永远保留预重写命令).所有这一切都假设他们没有做过工作; 使用git stash
以其他方式离开藏匿的变化.
如果其他开发人员使用功能分支,和/或git pull --rebase
不起作用例如,由于上游没有成立,他们必须重订其对-改写后提交顶工作.例如,在获取新的更改(git fetch
)之后,对于master
基于/ forked的分支origin/master
,需要运行
$ git rebase --onto origin/master origin/master@{1} master
Run Code Online (Sandbox Code Playgroud)
这origin/master@{1}
是预重写状态(在获取之前),请参阅gitrevisions.
替代解决方案是使用refs/replace / mechanism,自1.6.5版本开始在Git中提供.在此解决方案中,您为具有错误电子邮件的提交提供替换; 然后任何提取'替换'引用的人(fetch = +refs/replace/*:refs/replace/*
在他们的 适当位置像refspec 一样.git/config
)会透明地获得替换,而那些不获取这些引用的人会看到旧的提交.
程序如下:
查找所有提交错误电子邮件的提交,例如使用
$ git log --author=user@wrong.email --all
Run Code Online (Sandbox Code Playgroud)对于每个错误的提交,创建替换提交,并将其添加到对象数据库
$ git cat-file -p <ID of wrong commit> |
sed -e 's/user@wrong\.email/user@example.com/g' > tmp.txt
$ git hash-object -t commit -w tmp.txt
<ID of corrected commit>
Run Code Online (Sandbox Code Playgroud)现在您已经更正了对象数据库中的提交,您必须告诉git使用以下git replace
命令自动并透明地替换错误的提交:
$ git replace <ID of wrong commit> <ID of corrected commit>
Run Code Online (Sandbox Code Playgroud)最后,列出所有替换以检查此过程是否成功
$ git replace -l
Run Code Online (Sandbox Code Playgroud)
并检查是否有替换
$ git log --author=user@wrong.email --all
Run Code Online (Sandbox Code Playgroud)你当然可以自动执行这个程序......好吧,除了使用git replace
哪个没有(还)批处理模式,所以你必须使用shell循环,或者"手工"替换.
没有测试!因人而异.
请注意,使用refs/replace/
机制时可能会遇到一些粗糙的问题:它是新的,尚未经过很好的测试.
最快,最简单的方法是使用git rebase的--exec参数:
git rebase -i -p --exec 'git commit --amend --reset-author --no-edit'
Run Code Online (Sandbox Code Playgroud)
这将创建一个待办事项列表,如下所示:
pick ef11092 Blah blah blah
exec git commit --amend --reset-author --no-edit
pick 52d6391 Blah bloh bloo
exec git commit --amend --reset-author --no-edit
pick 30ebbfe Blah bluh bleh
exec git commit --amend --reset-author --no-edit
...
Run Code Online (Sandbox Code Playgroud)
并且这将全部自动进行,当您有数百次提交时,该方法也将起作用。
对于重置所有提交(包括第一次提交)到当前用户和当前时间戳:
git rebase --root --exec "git commit --amend --no-edit --date 'now' --reset-author"
Run Code Online (Sandbox Code Playgroud)
如果您想要修复的提交是最新的,只有其中几个,您可以使用组合git reset
和git stash
在配置正确的名称和电子邮件后再次提交它们.
序列将是这样的(对于2个错误的提交,没有挂起的更改):
git config user.name <good name>
git config user.email <good email>
git reset HEAD^
git stash
git reset HEAD^
git commit -a
git stash pop
git commit -a
Run Code Online (Sandbox Code Playgroud)
filter-repo
:您可以使用(推荐的替代品)的回调功能来更改与所有提交关联的名称和电子邮件:git-filter-repo
filter-branch
git filter-repo --name-callback 'return b"New Name"' --email-callback 'return b"newemail@gmail.com"'
Run Code Online (Sandbox Code Playgroud)
这比使用 的解决方案性能更高,并且可能更可靠filter-branch
。
请注意,上面的命令更改了所有提交的作者(和提交者),如果您想有效地“编辑”某个作者,并且只修改该特定作者的提交,请使用--commit-callback
如下选项:
git filter-repo --commit-callback '
old_email = b"oldemail@gmail.com"
new_email = b"newemail@gmail.com"
new_name = b"New Author"
if commit.author_email == old_email:
commit.author_email = new_email
commit.author_name = new_name
if commit.committer_email == old_email:
commit.committer_email = new_email
commit.committer_name = new_name
'
Run Code Online (Sandbox Code Playgroud)
(只需将上面命令中的old_email
、new_email
和变量更改为正确的值即可。)new_name
小智 5
如果您使用Eclipse与EGit,那么有一个非常简单的解决方案.
假设:您在本地分支"local_master_user_x"中提交,由于用户无效,无法将其推送到远程分支"master".
使用交互式rebase,您可以在每次要更改的提交后放置修改命令.例如:
pick a07cb86 Project tile template with full details and styling
x git commit --amend --reset-author -Chead
Run Code Online (Sandbox Code Playgroud)
请注意,git存储两个不同的电子邮件地址,一个用于提交者(提交更改的人),另一个用于作者(编写更改的人).
提交者信息不会在大多数地方显示,但您可以使用git log -1 --format=%cn,%ce
(或使用show
而不是log
指定特定提交)来查看它.
虽然更改上次提交的作者非常简单git commit --amend --author "Author Name <email@example.com>"
,但是对于提交者信息没有单行或参数可以做同样的事情.
解决方案是(暂时或不临时)更改您的用户信息,然后修改提交,这将更新提交者到您当前的信息:
git config user.email my_other_email@example.com
git commit --amend
Run Code Online (Sandbox Code Playgroud)
我们今天遇到了一个问题,即作者姓名中的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
Run Code Online (Sandbox Code Playgroud)
快速概述:将存储库签出到临时文件,签出所有远程分支,运行将重写历史记录的脚本,强制推送新状态,并告诉所有同事执行rebase pull以获取更改.
我们在OS X上运行它时遇到了麻烦,因为它在某些方面搞砸了提交消息中的行结尾,所以我们不得不在之后的Linux机器上重新运行它.
你的问题很常见.请参阅" 使用Mailmap修复Git中的作者列表 "
为了简单起见,我创建了一个脚本来简化流程:git-changemail
将该脚本放在路径上后,您可以发出如下命令:
更改当前分支上的作者匹配
$ git changemail -a old@email.com -n newname -m new@email.com
Run Code Online (Sandbox Code Playgroud)在<branch>和<branch2>上更改作者和提交者匹配.传递-f
给filter-branch以允许重写备份
$ git changemail -b old@email.com -n newname -m new@email.com -- -f <branch> <branch2>
Run Code Online (Sandbox Code Playgroud)在repo上显示现有用户
$ git changemail --show-both
Run Code Online (Sandbox Code Playgroud)顺便说一句,在进行更改后,使用以下命令从filter-branch清除备份:git-backup-clean
归档时间: |
|
查看次数: |
797318 次 |
最近记录: |