2011-08-10 41 views
4

我有一个很大的主项目有几个目录子树git推子目录到另一个主要的回购

我想在一个特定的子树的起源,这是一个单独的存储库的变化。

麻烦似乎是,我想要推动的当前子树最初并不是来自我想推入的存储库。它来自一个不同的回购,通过子树指南我发现通过谷歌搜索。它看起来非常相似。

大项目布局,其中important_subtree是我很担心的事情。

~/devel/bigproject 
    .git/ 
    some_subtree/ 
    other_subtree/ 
    important_subtree/ 
    abc.txt 
    efg.txt <--- new version 
    hij.txt 

而且important_subtree是 “强烈相关的” 到回购:

~/devel/important 
    .git/ 
    abc.txt 
    efg.txt <--- old version 
    hij.txt 

现在~/devel/bigproject/important_subtree/efg.txt已经改变了,我想的important_subtree推到回购~/devel/important。所以之后~/devel/important/efg.txt也有变化。

我设法做的唯一的事情是推动推一切bigproject重要,这显然不是我想要的。只应推动子树中的更改。

回答

2

这已经不再那么复杂了,您可以使用git filter-branch命令对您的repo进行克隆,以剔除不想要的子目录,然后推送到新的远程设备。

git clone <ORIG_REPO_DIR> <NEW_REPO_DIR> 
cd <NEW_REPO_DIR> 
git filter-branch --prune-empty --subdirectory-filter <THE_SUBDIR_TO_MAKE_NEW_ROOTDIR> master 
git push <MY_NEW_REMOTE_ORIGIN_URL> -f . 
+0

工程魅力。你应该提到'YOUR_SUBDIR'将成为改写回购的根目录(这正是我想要的)。另外,我不明白'推':我的新的远程网址?为什么-f(强制)?什么是“。”在这里呢?我无法重新创建您的推送。所以我去了'cd ..; git clone ' - 完美。 – towi

+0

推送是将提取的文件添加到新的远程。那编辑更清楚了吗? – jeremyjjbrown

+0

“新的遥控器?我想你说的是我不能将重写的repo推送到当前的远程,因为历史被重写了。所以最好初始化一个新的回购(裸机,在服务器上,不管),并将重写推到那里。 – towi

1

推动不同分支可能是一件非常棘手的事情。

也许最简单的方法是:

  1. 克隆你的“重要”回购再次从服务器。
  2. 在您的“bigproject”中生成补丁,其中包含您准备首先推送的更改(例如git format-patch)(您可能需要首先在边支中进行“较小”的提交,如果您的原始提交应该推送的混合文件以及不应该这样的文件)
  3. 在您的新“克隆”克隆中,应用修补程序(git am)
  4. 将“重要”的新克隆推送到其默认远程主站。现在推动只是一个简单的快速前进,不应该造成麻烦。
+0

<>这就是我的想法。谢谢。 – towi

3

我会推荐git-subtree除了git。它添加了一个git subtree split命令,可以执行您想要的操作。

git subtree split --prefix=important_subtree --branch=backport <subtree merge SHA1>^.. --onto=<imported SHA1> --rejoin 
git push ~/devel/important backport:master 

这樱桃挑选在bigproject因为你合并important作为一个子,只服用那些修改important_subtree/的变化。然后,它将它们作为新提交应用于您从~/devel/important导入的提交之上,并创建一个分支backport,您可以以正常方式推回。同样,--rejoin也可以让你在将来不需要使用提交ID,如果你想在更多的改变上重复这个过程。

关于author's blog post有更多解释。