2011-03-09 105 views
11

我將一個大的源代碼樹分成兩個獨立的組件和一個共享子模塊。爲了準備這個拆分,我首先將共享內容移動到一個「公共」目錄中,更新所有引用並進行提交。到現在爲止還挺好。現在我想將該目錄解壓縮到子模塊中。提取git子目錄,同時保留歷史WITH WITHWARE

一般情況下我這樣做與

git filter-branch --subdirectory-filter 

但是,在這種情況下,所有有趣的歷史發生了子目錄以外的,所以歷史會丟失。

據我所知,保留完整的歷史記錄是沒有意義的,因爲根本不會過濾掉任何數據。但是我並沒有真正想回到時間和構建的能力,我只想看看每個文件所屬的提交。

有沒有辦法保持過濾器分支行爲,同時保持個別文件的歷史?

回答

4

不是。 --subdirectory-filter有點特殊,因爲它實際上是顯着修改樹的內容(因爲它將事物向上移動一個或多個目錄嵌套層次)。

因此,在您要過濾的 子目錄之外的文件與可能作爲提交結果的一部分進行存儲的樹之間沒有很好的映射。

請記住,filter-branch是完全重寫您的歷史記錄 - 輸出是一組全新的提交,並且沒有任何與舊提交的「聯繫」,因此任何額外信息都必須作爲新的一部分來表達提交。

+2

這對我來說都是有意義的,但至少在原則上我可以想象得到一個目錄中的當前文件集並追溯每個文件的提交歷史記錄,並重新計數重命名。通過這種方式,每個提交對象涉及或不涉及子目錄中的文件。那些不涉及他們的人可能會被拋棄,而那些不會涉及他們的人可能會被重寫而忽略其他文件。 我不介意在我的歷史最後提出一個行動承諾,我只想保留所有的變化。 – 2011-03-09 09:05:22

+0

如果你要在子模塊中提交'git checkout'之一的「早期歷史記錄」提交,'git'會做什麼?如果該文件曾經是「高於」目前的存儲庫的頂級目錄,那麼Git無法處理該文件。 – Amber 2011-03-09 16:36:46

+0

我燒了一堆時間對此無濟於事......我仍然認爲這可以通過足夠聰明的人來完成。 – 2011-03-18 07:55:59

3

下面是我如何只是解決了類似的問題。我在一個準私人的「misc」資源庫中開始了一個項目,重新命名了一些文件,然後我想將項目上傳到GitHub https://github.com/kragen/aikidraw

$ git clone misc aikidraw 
$ cat > aikidraw-wanted 
aikidraw.js 
aikidraw.html 
caposketchra.html 
caposketchra.js 
jquery-1.2.6.js 
^D 
$ cd aikidraw 
$ git filter-branch --tree-filter 'bash -c "comm -23 <(/bin/ls | sort) <(sort ~/devel/aikidraw-wanted) | xargs rm -rf"' HEAD 

似乎已經好了,遠遠不能刪除點文件的工作,除了(如.git,好,.gitignore,糟糕),但顯然我的Git(1.6.0.4)的版本沒有git filter-branch --prune-empty。所以現在我會克隆新的,更小的回購協議(以使其更快它在網絡上覆制)和回購複製到另一臺機器具有的Git 1.7.2.5就可以了:

$ time git clone aikidraw aikidraw-smaller 
$ du -sh aikidraw/.git aikidraw-smaller/.git 
8.6M aikidraw/.git 
1.2M aikidraw-smaller/.git 

$ time rsync -Pav aikidraw-smaller panacea.canonical.org:devel/aikidraw/ 
real 1m23.251s 

,然後靈丹妙藥.canonical.org:

$ cd ~/devel/aikidraw/aikidraw-smaller # Oops. I hate rsync sometimes. 
$ git checkout # otherwise I get "Cannot rewrite branch(es) with a dirty working directory." 
$ git filter-branch --prune-empty HEAD 
$ cd ../.. 
$ mv aikidraw i-hate-rsync 
$ mv i-hate-rsync/aikidraw-smaller/ aikidraw 

然後回到我的上網本:現在

$ mv aikidraw aikidraw-big 
$ git clone panacea.canonical.org:devel/aikidraw 
$ du -sh aikidraw/.git 
268K aikidraw/.git 

,如果你有兩個目錄,而不是五個文件這樣做,你可能會在這一點上要重命名裏面的一切該使用git mv將其餘子目錄保存到存儲庫的根目錄中。在我的情況下,我已經完成了我的重命名。

$ git remote add github [email protected]:kragen/aikidraw.git 
$ git push github master 

希望這會有所幫助!

相關問題