2011-08-10 42 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有更多解釋。