我有一个Git存储库,其中包含许多子目录。现在我发现其中一个子目录与另一个子目录无关,应该分离到一个单独的存储库中。

如何在保留子目录中文件的历史记录的同时执行此操作?

我想我可以制作一个克隆并删除每个克隆中不需要的部分,但我想这会在检查旧版本等时提供完整的树。这可能是可以接受的,但我更希望能够假装这两个存储库没有共享的历史。

为了清楚起见,我有以下结构:

XYZ/
    .git/
    XY1/
    ABC/
    XY2/

但我想改为:

XYZ/
    .git/
    XY1/
    XY2/
ABC/
    .git/
    ABC/

当前回答

我发现,为了从新存储库中正确删除旧的历史记录,在过滤器分支步骤之后,您必须做更多的工作。

执行克隆和筛选:gitclone--没有硬链接foo bar;cd条gitfilter分支--子目录filter subdir/you/wente删除对旧历史的所有引用。“origin”是跟踪您的克隆,“original”是过滤器分支保存旧内容的位置:git远程rm源git update ref-d refs/original/refs/heads/mastergit reflog expire--expire=现在--全部即使是现在,您的历史记录也可能被保存在fsck不会触及的文件包中。将其撕成碎片,创建新的打包文件并删除未使用的对象:git重新打包-ad

过滤器分支手册中对此进行了解释。

其他回答

使用此筛选器命令删除子目录,同时保留标记和分支:

git filter-branch --index-filter \
"git rm -r -f --cached --ignore-unmatch DIR" --prune-empty \
--tag-name-filter cat -- --all

如上所述,我必须使用相反的解决方案(删除所有提交而不触及我的dir/subdr/targetdir),这似乎可以很好地去除大约95%的提交(根据需要)。然而,还有两个小问题。

首先,过滤器分支完成了一项出色的工作,删除了引入或修改代码的提交,但显然,合并提交在Gitiverse的站点之下。

截图:合并疯狂!

这是一个我可能可以忍受的美容问题(他说……慢慢后退,眼睛转向)。

第二,剩下的几个提交几乎都是重复的!我似乎获得了第二个多余的时间线,它几乎涵盖了整个项目的历史。有趣的是(你可以从下面的图片中看到),我的三个本地分支并不都在同一个时间线上(这就是为什么它存在,而不仅仅是垃圾收集)。

尖叫:双双,Git过滤器分支样式

我唯一能想到的是,其中一个被删除的提交可能是过滤器分支实际删除的单个合并提交,并且创建了并行时间线,因为每个现在未合并的链都有自己的提交副本。(耸耸肩,我的TARDiS在哪里?)我很确定我能解决这个问题,尽管我真的很想知道它是怎么发生的。

对于疯狂的mergefest-O-RAMA,我很可能会把它单独放在一边,因为它在我的承诺历史中根深蒂固,每当我走近时,它都会威胁我——它似乎并没有真正引起任何非外观问题,因为在Tower.app中它非常漂亮。

把这个放到你的gitconfig中:

reduce-to-subfolder = !sh -c 'git filter-branch --tag-name-filter cat --prune-empty --subdirectory-filter cookbooks/unicorn HEAD && git reset --hard && git for-each-ref refs/original/ | cut -f 2 | xargs -n 1 git update-ref -d && git reflog expire --expire=now --all && git gc --aggressive --prune=now && git remote rm origin'

我确信git子树很好,很好,但我想移动的git托管代码子目录都在eclipse中。所以,如果你使用egit,这非常容易。将要移动的项目与团队->断开连接,然后团队->将其共享到新位置。默认情况下,它将尝试使用旧的回购位置,但您可以取消选中使用现有选择并选择新位置来移动它。大家都来了。

您可以轻松尝试https://help.github.com/enterprise/2.15/user/articles/splitting-a-subfolder-out-into-a-new-repository/

这对我有用。我在上面给出的步骤中遇到的问题是

在此命令中,gitfilter branch--prune empty--子目录筛选器FOLDER-NAME branch-NAMEBRANCH-NAME是主如果由于保护问题提交时最后一步失败,请遵循以下步骤:https://docs.gitlab.com/ee/user/project/protected_branches.html