我有一个大型存储库,目前在顶级子文件夹中包含多个项目,例如/a
,/b
,/c
和/d
。
现在我想将该存储库拆分为两个不同的存储库:一个包含/a
和/b
,另一个包含/c
和/d
。
我知道git filter-branch --subdirectory-filter
,它非常适合提取单个目录,但似乎无法一次提取多个目录。
我也知道git filter-branch --prune-empty --tree-filter
,这将允许我删除所有内容,但这两个想要的目录。这感觉不完全正确,因为我必须手动指定可能存在的所有顶级目录。
有没有更好的方法从大型存储库中提取两个目录?
PS:当然,使用git filter-branch
之外的其他东西的任何好解决方案都可以。 ;)
答案 0 :(得分:45)
使用
git filter-branch -f --prune-empty --tree-filter 'bash preserve-only.sh a b' -- --all
其中preserve-only.sh
是:
IFS=':'
GLOBIGNORE="$*"
rm -rf *
这应该从所有分支的所有提交中删除除a
和b
之外的所有内容,这应该与提取确切的给定目录相同。
要完成实际拆分,您可以使用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