2012-01-03 97 views
4

我在一個子目錄中有一個存儲庫,現在我想在版本控制下也有父目錄 ,但保留存儲庫的當前歷史記錄。如何擴展git存儲庫

因此,與下面的樹:

c目前持股的倉庫,但我想有一個倉庫在a,並且包括內c所有的歷史。

我敢肯定有一種方法可以做到這一點,也許有一些git filter-branch?我不想使用子模塊,我希望最終擁有一個存儲庫。

回答

2

你有一個選擇:

您可以簡單地將當前結構轉換爲新結構。然後將整個回購上升一級。 git add -A將添加所有這些是一堆刪除和新文件添加的更改。 git status會將它們顯示爲已移動。每個對象都存儲一次,不管它在哪個路徑上,所以這不會是一個昂貴的操作。這將是最簡單的選擇。此時你也可以放入其他高級目錄。

而在C:

mkdir b 
cd b 
mkdir c 
mv <all other objects from top level> c 
git add -A 
git commit -m "moved everything" 
mv c a 
# clean up 

git會確定的事實,文件被移動,如果你正在做的合併和幫助你。

或者,您可以使用過濾器分支來更改歷史記錄(如果您喜歡),但所有提交將具有不同的SHA1。這可能是不可取的。

+0

這是一個簡單而巧妙的解決方案。它仍然有問題,歷史路徑是不準確的(可以通過@Tobu提供的'過濾branch'命令更改)離開,但歷史是線性的,直觀的,以回購的演變。謝謝! – englebip 2012-01-03 22:53:15

+0

一對夫婦關於命令上述表示的:1)的前三個我可以合併成'MKDIR -p B/C',然後改變'MV B/C' <從頂層所有其他對象>的目的地; 2)不要(愚蠢地)像我最後一個命令'mv * b/c'那樣做動作;你將遞歸地拷貝'b/c/b/c/b/c ...'直到填滿你的硬盤。 – englebip 2012-01-03 22:56:39

3

您需要的是創建新的外部存儲庫,並使用子樹合併來合併內部存儲庫。 There's a quick HOWTO at the bottom of this page.。你應該暫時將c移到a/b之外,這些指令期望c樹在它的最終位置還不存在。


如果你想使C出現嵌套在過去歷史(和都還好用改變sha1s),使用過濾器分支代替(credit):

git filter-branch --index-filter \ 
    'git ls-files -s | sed "s#\t#&a/b/c/#" | 
      GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ 
        git update-index --index-info && 
    mv -T "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' -- --all 
+0

該解決方案將保留現有的提交的SHA1的,但所有現有的提交將仍然具有樹形結構中,有今天。從合併點開始,您的樹結構將反映您想要的更深層次的回購。如果你很高興在歷史上有一個淺層樹狀結構,那麼這可能是你想要去做的方式。 – 2012-01-03 21:45:10

+0

除了@Kevin的評論,這幾乎完美無缺。確實,這是歷史發生的事情。這不是一個大問題,但我將如何改變合併提交的路徑? 完成後,我使用的是: 'git remote add c_new -f ../c_repo; git read-tree --prefix = b/c/-u c_new/master; git commit -m'將b/c合併成'; git pull -s子樹c_new master; git remote rm c_new' – englebip 2012-01-03 22:13:58

+0

sha1s會改變。過濾器分支不是我會推薦的在項目中間的回購。我保留這個在罕見的情況下,我從一箇舊項目開始一個新項目。 – 2012-01-03 22:52:24

0

不是一個簡單的MV工作?所有'c'只會顯示爲重命名。

事情是這樣的:(請不要剪切和粘貼準確,因爲我還沒有嘗試過這個..剛剛得到的要點..)

cp -r /someroot/a/b/c /tmp/tmproot/c # make a full backup of the given repository 
rm -Rf /someroot/a/b/c     # completely remove c, leaving only a/b 
mv -r /someroot/a /tmp/tmproot  # moves a/b to the repository 
cd /tmp/tmproot 
git mv -r c a/b       # git-moves c into a/b, so all history of c is retained 

現在你的/ tmp/tmproot目錄下應該有一個與C的歷史/ b/C保留

rm /someroot 
mv -Rf /tmp/tmproot /someroot    # replace the old rep with your new one 

現在添加的一切,並承諾

+0

這確實是一個好主意,並且非常類似於@ Adam的。我嘗試過那個,並且運行良好。謝謝! – englebip 2012-01-03 23:00:29