在具有历史的 Git 中导出子树

我的 Git 存储库中有一个文件夹,我想把它移到它自己的存储库中。有没有可能将该文件夹的历史记录与该文件夹一起移动?

我以前只是在子文件夹中执行 git rm -r --cached subfolder/git init操作。但是,历史记录不会导入到新的存储库中。

13190 次浏览

引用 git-filter-branch(1)中的一个例子

要重写存储库,使其看起来像 Foodir/已经成为其项目根目录,并丢弃所有其他历史记录:

git filter-branch --subdirectory-filter foodir -- --all

因此,例如,您可以将库子目录转换为它自己的存储库。注意——它将过滤器分支选项与修订选项分开,还有—— all 用于重写所有分支和标记。

对于任何在2021年(或更晚)到达这里的人来说,git 过滤器分支都不是核心 git 团队强烈推荐的。

警告 Git filter-Branch 有太多的缺陷,可能会对预期的历史重写造成不明显的破坏(并且由于它的性能非常糟糕,您几乎没有时间来研究这些问题)。这些安全性和性能问题不能向后兼容地修复,因此不建议使用它。请使用替代的历史过滤工具,如 git filter-repo。如果您仍然需要使用 git 过滤器,请仔细阅读安全(和性能) ,了解过滤器的地雷分支,然后警惕地避免尽可能多的危险列在合理的可能。

相反,推荐的工具是 Git-filter-repo,它使这个问题的工作变得容易

git filter-repo --path subfolder/   # Filter the repo to just the sub-dir
git mv subfolder/* .                # Move the contents of the sub-dir to the root
git commit -m "Filtered from main repo"