这个问题听起来与这里提出的许多问题相似,但令人讨厌的不同。
我有一个 git 存储库,它曾经是 svn 存储库(曾经是 cvs 存储库)。这包含可追溯到 1999 年左右的数据。
是时候将这个存储库拆分为几个不同的存储库了,以保留所有这些丰富的历史。但是,存储库的结构经常发生变化。当前所有的项目都来自一个基础项目,这个基础项目增长到几个项目,然后缩小到两个项目,然后再次增长。代码已被移动,但从未重复;它现在已经在几个成熟的项目之一中找到了最后的安息之地。
如果我想保留历史记录,这使得拆分存储库变得非常困难。使用 git-filter-branch 似乎是正确的方法,但所有这些似乎都破解了存储库的一部分并用它们截断了历史记录。
编辑添加为了澄清,这是一个小例子,假装我在存储库的根目录中。假设存储库如下所示:
foo/
bar/
file.txt
baz/
现在假设我编辑file.txt
. 然后我将其重命名为newfile.txt
. 然后我再次编辑内容。然后我将此文件移出bar/
和移入baz/
. 我的存储库现在看起来像这样:
foo/
bar/
baz/
newfile.txt
好的,现在假设我想拆分baz/
到它自己的存储库中。使用 git filter-branch 或使用 git subtree split 将丢失所有提交消息和历史记录,以便newfile.txt
在它位于内部bar/
和命名时返回file.txt
。
我知道查看历史版本可能很疯狂;它可能引用了一个叫做的东西,../bar/
或者它可能引用了一个不存在的无效目录并严重失败。我不在乎,只要我可以查看任何特定修订版的文件内容即可。
结束编辑
我想做的事情似乎有两条路径:
克隆存储库 N 次,在该存储库中保留我想要的文件夹(通过 git rm-ing 其他文件夹),并以某种方式破解任何最终不会引用 HEAD 中文件的修订。我意识到这会产生一些负面影响,因为检查旧版本不会提供有意义的代码库——我不在乎。为了做到这一点,我需要找到一种方法来获取来自 HEAD 中存在的所有文件的所有路径,我可以使用丑陋的脚本来做到这一点。
为每个索引期间存储库的样子构建某种历史索引。使用树过滤器并删除在其各自版本中不匹配的文件。然后,删除 HEAD 中未出现或源自文件的文件。
是否可以找到所有未出现在 HEAD 中的文件并删除与它们相关的任何历史记录?我不关心恢复已被长期删除的文件,这似乎是我问题的症结所在。
替代解决方案也将受到赞赏。我对 git 比较陌生,所以我可能遗漏了一些明显的东西。