2017-01-23 15 views
10

我会尽量保持这个简短。如何合并来自包含另一个目录子集的分支的更改?

我们有一个充当SVN镜像的git存储库(由BitBucket管理)。此回购包含在公司,因为刚开始的时候项目,并有每一个开发商克隆它不是一个合理的要求(25 + 33GiB完整克隆和15 +吉布浅),但即便如此,我们并不需要一个完整的克隆整个存储库的一部分,只是其中的一部分目录。

使用git-subtree,我设法分割出所有感兴趣的目录,并认为我们可以使用git-subtree add将这些目录添加回本地回购站。这个过程对svn仓库是透明的。这工作得很好,尺寸更易于管理(9 + 6GiB完整克隆和8GiB浅)。问题是我不知道我们如何才能在这些“部分克隆”中进行修改并将它们合并回主分支。

我认为我们可以使用通常的pull请求来让它们进入,但由于分支树不同,它不像我想要的那样工作(缺少的目录被视为清除)。我只想合并克隆目录的更改并保持其他目录不变。

我不认为使用稀疏结帐会有帮助,因为我们仍然需要克隆完整的回购才能使其工作,这正是我想要避免的。

是否有一些命令组合可用于使这一切工作?


下面是我用来分割出的目录和检出感兴趣的目录(修改)脚本:

split_projects.sh
我以前的git-子树拆分并重新加入的目录和使用的混帐 - 以改善重新分裂的速度(仅处理新的提交)。需要注意的是归队是主要致力于回购(我不是愿意尝试提交该特别是与SVN镜像)。

initial_setup.sh
这是准备本地回购的脚本。供Windows用户使用,其中许多人对git或命令行工具不熟悉。

checkout_projects.sh
实际的结帐脚本。

还有另一个从拆分子目录中获取更新,但我没有在这里包括它。

+0

合并的子树选项有什么问题? – jthill

+0

我的理解是,使用该策略会合并分支,其中一个完全包含在另一个分支中。即分支A已经是分支B的子树。在我的情况下,分支A包含分支B的子目录,并且不起作用。 –

+0

您可能需要联系邮件列表([email protected])才能获得支持。然而,我的直觉是,可能没有解决方案,因为你正在寻求以某种方式将在子树中所做的更改应用于根回购,并且我无法想象如果没有关于根回购。如果您的开发人员使用Windows,那么最近开源的GVFS项目可能实际上就是您想要的。 – Pockets

回答

2
你的情况

恐怕你必须使用樱桃挑选来的变化移动到原来的仓库

4

如果您不希望一些变化重新合并,做您的合并--no-commit,并撤消这些变化提交之前的合并结果。对于不需要的删除,只需要git checkout即可。对于不需要的更改,请登录git checkout --patch

另一种选择,这可能会风,如果它真的只是在顶层子树从合并分支缺少折叠起来简单,就是做合并和修改它之后,一个(git ls-tree @; git ls-tree @^1|grep ^04)|sort -usk4 | git mktree会生成正确的树很轻松了,所以

fixup=`(git ls-tree @; git ls-tree @^1|grep ^04)|sort -usk4|git mktree` 

commit=`git show -s --pretty=%B @|git commit-tree -p @^1 -p @^2 $fixup` 

git update-ref -m 'fold in missing subdirectories' @ $commit 

合并后,你就完成了。

+0

我想我可以设置一个脚本来做到这一点。可能将拉请求集成到一个特殊的分支,我将创建。 –

+0

听起来可行。 – jthill

+0

当我有更多时间来处理这个问题时(现在是在加力燃烧器上),我将朝这个方向前进。这将是我能得到的最接近的。 –

2

最好的解决方案我是为你运行在一个浅克隆根库中的稀疏检出以下:

git checkout -b branch-to-PR-in 
git fetch remote-with-subtree-as-root 
git merge -s recursive -X theirs -X subtree=path/in/root/to/subtree/ remote-with-subtree-as-root/master --allow-unrelated-histories -X theirs 
2

如果我正确理解你的脚本:

bigrepo,一个$project有其历史上分支subdirs/$project,其在回购的根目录中的内容
例如:如果您运行git checkout subdirs/$projectbigrepo,该项目所在的内容在/(不在一些额外的子目录中)。

如果是这样的话:

我想git subdir push -P $project序列应该工作:

  • 一个从分裂回购的任何“本地仓库”来分割回购
  • 一个bigrepo
+0

虽然这将推动拆分分支,我最终想要让他们回到主分支。这种方式从git用户的变化回到svn回购。 –

+0

@JeffMercado:从文档('git help subtree')你应该可以推送到你喜欢的任何分支。否则,你可以建立你的树并手工完成,就像@jthill所建议的那样。 – LeGEC

相关问题