【问题标题】:extract multiple directories using git-filter-branch使用 git-filter-branch 提取多个目录
【发布时间】:2013-11-13 12:59:31
【问题描述】:

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

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

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

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

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

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

【问题讨论】:

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


【解决方案1】:

使用

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

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

【讨论】:

  • 索引过滤器选项是迄今为止最好的。一个建议:将--ignore-unmatch 添加到git rm 语句以抑制. 不匹配任何内容的错误(提交后的空仓库)。
  • 太棒了,正是我想要的。也适用于嵌套目录。谢谢!
  • 对于标签,我添加了--tag-name-filter cat
  • 可能应该更多地强调使用index-filter 的第二个选项。由于注意力短暂,我只是从第一个命令开始并停止阅读。这需要几个小时才能完成我们的大型回购。幸运的是,我回到这个帖子发现了“更新”,这在几秒钟内就奏效了。
  • 此答案已过时,现在更喜欢git filter-repo 方式,请参阅下面@Cem.S 的答案!!
【解决方案2】:

在搜索并尝试了建议的解决方案之后,现在推荐的做法似乎是使用git-filter-repo(请参阅here

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

【讨论】:

  • 目前在windows上安装有一些问题,但是安装好之后就很好用了,简单
【解决方案3】:

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

首先创建两个分支:

git branch br1
git branch br2

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

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

【讨论】:

    【解决方案4】:

    我更喜欢这个

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-15
      • 2011-08-06
      • 2013-11-07
      • 2013-03-29
      • 2020-07-22
      • 2012-04-29
      相关资源
      最近更新 更多