我如何从git存储库中删除作者?
如果我创建了一个Git仓库并公开发布它(例如,在GitHub等),并且我收到了贡献者对仓库的请求,无论出于何种原因删除或遮盖了它们的名称,有没有办法轻松实现?
基本上,我有这样的要求,可能想用“匿名贡献者”或者他们的电子邮件地址的SHA-1哈希替代他们的名字和电子邮件地址或类似的东西。
Jeff非常正确,正确的轨道是git filter-branch。 它期望一个与环境变量一起使用的脚本。 对于你的用例,你可能想要这样的东西:
git filter-branch --env-filter '
if [ "$GIT_AUTHOR_NAME" = "Niko Schwarz" ]; then
export GIT_AUTHOR_NAME="Jon Doe" GIT_AUTHOR_EMAIL="john@bugmenot.com";
fi
'
你可以测试它是这样工作的:
$ cd /tmp
$ mkdir filter-branch && cd filter-branch
$ git init
Initialized empty Git repository in /private/tmp/filter-branch/.git/
$
$ touch hi && git add . && git commit -m bla
[master (root-commit) 081f7f5] bla
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 hi
$ echo howdi >> hi && git commit -a -m bla
[master a466a18] bla
1 files changed, 1 insertions(+), 0 deletions(-)
$ git log
commit a466a18e4dc48908f7ba52f8a373dab49a6cfee4
Author: Niko Schwarz <niko.schwarz@gmail.com>
Date: Thu Aug 12 09:43:44 2010 +0200
bla
commit 081f7f50921edc703b55c04654218fe95d09dc3c
Author: Niko Schwarz <niko.schwarz@gmail.com>
Date: Thu Aug 12 09:43:34 2010 +0200
bla
$
$ git filter-branch --env-filter '
> if [ "$GIT_AUTHOR_NAME" = "Niko Schwarz" ]; then
> export GIT_AUTHOR_NAME="Jon Doe" GIT_AUTHOR_EMAIL="john@bugmenot.com";
> fi
> '
Rewrite a466a18e4dc48908f7ba52f8a373dab49a6cfee4 (2/2)
Ref 'refs/heads/master' was rewritten
$ git log
commit 5f0dfc0dc9a325a3f3aaf4575369f15b0fb21fe9
Author: Jon Doe <john@bugmenot.com>
Date: Thu Aug 12 09:43:44 2010 +0200
bla
commit 3cf865fa0a43d2343b4fb6c679c12fc23f7c6015
Author: Jon Doe <john@bugmenot.com>
Date: Thu Aug 12 09:43:34 2010 +0200
bla
请小心。 没有办法删除作者的名字而不会使所有后来的提交哈希无效。 这将使后来合并使用您的存储库的人们的痛苦。
如果你不得不为一个用户或所有用户“匿名”一个git仓库,Git 2.2(2014年11月)提供了一个有趣的功能,它具有改进和增强的git fast-export
:
见Jeff King( peff
)提交a872275和提交75d3d65:
教导fast-export
--anonymize
选项:
有时用户想要报告他们在其存储库中遇到的错误,但他们无权共享存储库的内容。
如果他们能够创建一个与其历史和树形状相似的存储库,但不泄漏任何信息将会很有用。
这个“匿名”存储库然后可以与开发人员共享(假设它仍然复制原始问题)。
此修补程序实现了“ - --anonymize
”选项以进行fast-export
,从而生成可以重新创建此类存储库的流。
生成一个单一的数据流使调用者可以很容易地确认他们没有泄漏任何有用的信息。 您可以通过运行如下命令获得共享内容的概述:
git fast-export --anonymize --all |
perl -pe 's/d+/X/g' |
sort -u |
less
这将显示我们生成的每条唯一线,以任何数字为模(每个匿名标记都被分配一个数字,例如“ User 0
”,并且我们在输出中一致地替换它)。
除了匿名化之外, 这产生的测试用例相对较小(与原始存储库相比)并且生成速度快(与使用filter-branch
或自行修改fast-export
输出的输出相比)
文档:
如果给出--anonymize
选项,git将尝试从存储库中删除所有标识信息,同时仍保留足够的原始树和历史记录模式以重现一些错误。
使用这个选项,git会用匿名数据替换输出中的所有refnames,路径,blob内容,提交和标记消息,名称和电子邮件地址 。
相同字符串的两个实例将被等同替换(例如,对同一作者的两个提交在输出中将具有相同的匿名作者,但与原作者字符串没有相似之处)。
提交,分支和标签之间的关系被保留,并且提交时间戳(但提交消息和引用名称与原始文件没有相似之处)。
保留树的相对构成(例如,如果您有一棵具有10个文件和3棵树的根树,输出也是如此),但是它们的名称和文件内容将被替换。
您可以在本地存储库中进行更改, git commit --amend
适当的提交(您添加名称的位置),然后使用您的版本库更新git push --force
。
提交者名字的原始提交仍然可以在reflog中找到(直到它过期,但是需要花费很多努力才能找到它),如果这是一个问题,您可以从reflog中删除特定的提交 - 参见git help reflog
获取语法以及如何在列表中找到它。