使用git-filter-branch提取多个目录

时间:2013-11-13 12:59:31

标签: git git-svn git-rebase git-filter-branch

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

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

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

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

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

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

4 个答案:

答案 0 :(得分:45)

使用

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

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

答案 1 :(得分:1)

经过研究并尝试了建议的解决方案之后,似乎推荐的方法是使用git-filter-repo(请参见here

git filter-repo --path a --path b

答案 2 :(得分:0)

我不知道有比tree-filter更好的方法。所以你已经掌握了所需的所有信息。现在就去做吧!

首先创建两个分支:

git branch br1
git branch br2

现在为每个分支检查,然后使用tree-filter过滤它。

然后你可以通过推出它们,或者通过克隆或拉入它们将它们拆分成单独的目录。

答案 3 :(得分:0)

我更喜欢这个

git filter-branch -f --prune-empty --tree-filter "ls -I a -I b | xargs rm -rf"  -- --all