我有一个Git存储库,其中包含许多子目录。现在我发现其中一个子目录与另一个子目录无关,应该分离到一个单独的存储库中。
如何在保留子目录中文件的历史记录的同时执行此操作?
我想我可以制作一个克隆并删除每个克隆中不需要的部分,但我想这会在检查旧版本等时提供完整的树。这可能是可以接受的,但我更希望能够假装这两个存储库没有共享的历史。
为了清楚起见,我有以下结构:
XYZ/
.git/
XY1/
ABC/
XY2/
但我想改为:
XYZ/
.git/
XY1/
XY2/
ABC/
.git/
ABC/
我找到了非常直接的解决方案,这个想法是复制存储库,然后删除不必要的部分。这是它的工作原理:
1) 克隆要拆分的存储库
git clone git@git.thehost.io:testrepo/test.git
2) 移动到git文件夹
cd test/
2) 删除不必要的文件夹并提交
rm -r ABC/
git add .
enter code here
git commit -m 'Remove ABC'
3) 使用BFG从历史记录中删除不必要的文件夹
cd ..
java -jar bfg.jar --delete-folders "{ABC}" test
cd test/
git reflog expire --expire=now --all && git gc --prune=now --aggressive
对于多个文件夹,可以使用逗号java-jar bfg.jar--删除文件夹“{ABC1,ABC2}”metric.git
4) 检查历史记录是否不包含您刚刚删除的文件/文件夹
git log --diff-filter=D --summary | grep delete
5) 现在您有了没有ABC的干净存储库,所以把它推到新的原点
remote add origin git@github.com:username/new_repo
git push -u origin master
就是这样。您可以重复这些步骤来获取另一个存储库,
只需在步骤3中删除XY1、XY2并重命名XYZ->ABC
如上所述,我必须使用相反的解决方案(删除所有提交而不触及我的dir/subdr/targetdir),这似乎可以很好地去除大约95%的提交(根据需要)。然而,还有两个小问题。
首先,过滤器分支完成了一项出色的工作,删除了引入或修改代码的提交,但显然,合并提交在Gitiverse的站点之下。
截图:合并疯狂!
这是一个我可能可以忍受的美容问题(他说……慢慢后退,眼睛转向)。
第二,剩下的几个提交几乎都是重复的!我似乎获得了第二个多余的时间线,它几乎涵盖了整个项目的历史。有趣的是(你可以从下面的图片中看到),我的三个本地分支并不都在同一个时间线上(这就是为什么它存在,而不仅仅是垃圾收集)。
尖叫:双双,Git过滤器分支样式
我唯一能想到的是,其中一个被删除的提交可能是过滤器分支实际删除的单个合并提交,并且创建了并行时间线,因为每个现在未合并的链都有自己的提交副本。(耸耸肩,我的TARDiS在哪里?)我很确定我能解决这个问题,尽管我真的很想知道它是怎么发生的。
对于疯狂的mergefest-O-RAMA,我很可能会把它单独放在一边,因为它在我的承诺历史中根深蒂固,每当我走近时,它都会威胁我——它似乎并没有真正引起任何非外观问题,因为在Tower.app中它非常漂亮。