26

我有一个大存储库,目前在顶级子文件夹中包含多个项目,例如/a/b/c/d.

现在我想将该存储库拆分为两个不同的存储库:一个包含/aand/b另一个包含/cand /d

我知道git filter-branch --subdirectory-filter,这非常适合提取单个目录,但似乎无法一次提取多个目录。

我也知道git filter-branch --prune-empty --tree-filter,这将允许我删除所有内容,但两个想要的目录。这感觉不完全正确,因为我必须手动指定所有可能存在的顶级目录。

有没有更好的方法从大存储库中提取两个目录?

PS:当然,使用其他东西的任何好的解决方案git filter-branch都可以。;)

4

4 回答 4

49

采用

git filter-branch -f --prune-empty --tree-filter 'bash preserve-only.sh a b' -- --all

哪里preserve-only.sh是:

IFS=':'
GLOBIGNORE="$*"
rm -rf *

这应该从所有分支的所有提交中删除所有内容,这应该与准确提取给定目录相同ab

要完成实际拆分,您可以使用过滤器rm -rf a b来获取第一次运行中未提取的所有更改。


更新:在尝试加快使用速度时,--index-filter我找到了一个更简单的解决方案:

git filter-branch -f --prune-empty --index-filter \
  'git rm --cached -r -q -- . ; git reset -q $GIT_COMMIT -- a b' -- --all

这只是删除所有内容,然后恢复给定的目录。

于 2013-11-13T15:33:46.133 回答
6

在四处搜索并尝试了建议的解决方案之后,现在推荐的做法似乎是git-filter-repo(见这里

git filter-repo --path a --path b
于 2020-09-08T13:18:40.873 回答
0

我不知道有什么比tree-filter这更好的方法。因此,您已经拥有所需的所有信息。现在就去做吧!

首先创建两个分支:

git branch br1
git branch br2

现在对于每个分支,检查它,然后使用tree-filter.

然后,您可以通过将它们推出或克隆或拉入它们来将它们拆分到单独的目录中。

于 2013-11-13T14:14:34.530 回答
0

我更喜欢这个

git filter-branch -f --prune-empty --tree-filter "ls -I a -I b | xargs rm -rf"  -- --all
于 2014-09-25T04:44:52.533 回答