我想知道使用git filter-branch ... 'git rm ..'
从存储库历史记录中清除数据(参见this link)的副作用是针对大型分布式项目的。
我们的项目基于github,其中有几个重要的叉子,每个都有很多用户,我希望尽量减少影响。
谢谢!
编辑:我的目标是删除敏感数据。虽然没有“把猫放回袋子里”,但重要的是我们要从回购中删除它。
答案 0 :(得分:2)
您没有说明为什么要清除数据,但主要有两个原因。
第一个(在我的经验中最常见)是你有一些敏感信息需要删除。实际上,这就是您链接到的页面用于标题的内容。
在一个广泛分布的大型项目中,我会强烈避免这种情况。
这是一个拥有许多分支和贡献者的大型存储库这一事实使这些观点更加重要。不要重写项目的历史记录,只需删除所有活动分支中的文件,更改密钥/密码/等等,然后继续。
清除数据的另一个主要原因是减少存储库的大小,例如:适应GitHub的存储库大小限制。如果这是你的目标,你可能没有那么多的选择,因为只有这么多的方法。
关于修改共享历史记录的修改:
这是修改共享历史记录的主要问题:提交的哈希值是根据许多内容计算的,包括文件内容,提交的时间戳,提交消息和父提交的哈希值。
最后一个很重要 - 如果以任何方式修改一个提交,其哈希值会发生变化。如果一个提交的哈希值发生变化,所有后代提交的哈希值都会发生变化。
想象一下你的存储库。到处都有很多很多的副本。每个fork中的每个贡献者都有一个副本,每个副本共享历史记录。当你push
提交给GitHub时,它们可以通过GitHub的现有提交来解决,因为提交形成的图是相同的。它具有相同的结构,并且所有旧的提交哈希都匹配。当来自GitHub的fetch
时,相同的逻辑让我得到更新的提交。每个分叉副本的工作原理相同。
现在假设您在存储库的filter-branch
分支上使用master
来删除某些文件。包含该文件的最早提交将被更改,将会更改每个其他后代提交。现在你尝试更新GitHub,但你不能,因为无法解决GitHub的提交网络更新。提交哈希不再匹配。你必须push --force
。
但是在您push --force
更改后,存储库的每个其他副本现在都包含不再与上游历史记录相匹配的提交。每个分支的每个副本都将在merge --ff-only
上失败。必须更新每个fork的每个副本以匹配新的不同历史记录。可能是手动。
理论上,这可以完成。如果只有几个存储库副本,它甚至可以管理。但是,如果有一个成功的公共存储库,有许多分叉,你将如何协调这项工作? 每个用户都必须跳过箍,手动合并origin/master
,现在已经明显偏离master
,只是为了适应您的更改。你有没有试过合并两个很久以前分歧的分支?不好玩。
如果这些用户在旅途中工作,从master
开始分配尚未合并的工作,则他们必须rebase
在新分支上工作。并再次测试它。并确保与处理更改的其他人协调这些更改。
基本上,所有分支中所有分支的所有工作都必须被冻结,直到这个过程被整理出来。
即使在所有这些之后,您的敏感文件仍然被泄露。某些用户可能无法删除这些文件的副本,或者可能已复制了您的密码或密钥。旧文件可以缓存在某个服务器上。这些文件中的信息仍然受到损害,您所做的任何工作都没有以任何方式改变。
一个更好,更好的选择是承认你做的任何错误,引入一个新的提交来反转它,让所有祖先提交原样,并继续前进。
处理泄露信息的唯一方式是改变它。