2016-06-13 57 views
2

我被帶到版本控制項目,以前沒有在版本控制。停止git歷史記錄,然後再重新組合在一起

沒有想到,我將所有文件添加到存儲庫,並開始跟蹤它,只要我開始工作。

現在版本庫非常龐大,無法推送到git hub。所以我開始刪除所有過多的文件,並使用git filter-branch使用此命令從歷史記錄中消除它們。

sudo git log --all --pretty=format: --name-only --diff-filter=D | sort -u | while read -r line; do sudo git filter-branch -f --tree-filter "rm -rf { $line }" HEAD; done 

問題?有太多過多的文件,而且這太長了,彌賽亞可能會在完成之前返回,我需要迅速將它提交給github。

所以加快的過程中,我看到了,我可以只犯一個孤兒分支

git checkout --orphan <new-branch-name> 

所以剛拿到移動最新的文件,我很樂意做的是推動眼前這個承諾github,繼續運行清理操作,然後在完成後將兩個分支重新粘在一起。

這樣

1-----10 
     1a------Xa (1a = 10) 

變爲

1-----10-1a------Xa 

或可能

1------10------Xa 

因此,在年底,我們從字面上保存所有的歷史。

這可能嗎?我處於緊張時期,不想失去一切。

+0

通過「過多的文件」,你的意思是大的二進制文件? – Makoto

+0

大部分是,但也有一些代碼文件。 –

+0

所有已被刪除,只是不是從存儲庫,並過濾器分支正在永遠 –

回答

2

這是不可能的如描述,因爲提交的ID(「真名」)是它的哈希校驗和,其中包括它的所有歷史記錄。因此,在包含兩個分支這五個提交回購:

A--B--C--D <-- with-big-files 

     D' <-- cleaned 

你可以把任一分支,但你永遠無法讓D'有,因爲作爲前身,任何其他承諾。 D'是一個根提交,並且始終是根提交。

什麼你可以做的是,例如,添加此cleaned2分支:

A--B--C--D <-- with-big-files 

     D'  <-- cleaned 

      A'-B'-C' <-- cleaned2 

然後合併

A--B--C--D <-- with-big-files 

     D'---------E <-- cleaned 
       /
      A'-B'-C' <-- cleaned2 

,然後丟棄cleaned2。 (如果你喜歡,cleaned2可以包括D'',它是D和/或D'的副本,但是具有C'作爲其父項。)

需要注意的是,無論你是否使用git filter-branch或BFG,甚至這種手工方法,你最終得到的是一堆複製原始的提交,你已經採取了巨大的文件出了副本的


編輯:這不是一個問題的答案,但我想我要補充這方面說明。你已經確定過濾器分支太慢了,但現在解決了一個不同的問題,而不是簡單地加快過濾器分支。

首先,您使用的濾鏡git filter-branch--tree-filter)是最慢的方法。它會快得多(儘管仍然不快),以每個這樣的清除作爲--index-filter

其次,實際上更重要的,而不是刪除一個合格的每個文件完全複製每一個存儲庫中的承諾,你應該做的一個傳過來的每個存儲庫中的承諾刪除所有這些文件(仍使用索引過濾器,以避免將每個提交複製到工作樹)。

驅動所有這一切的關鍵是git filter-branch的工作方式,我上面提到過。這是不可能的,更改一個提交,在Git中,所以像所有的Git命令,filter-branch沒有。它只是似乎到,並使它看起來好像一些提交(S)被改變,Git 複製每個這樣的提交到新的提交,然後隱藏原件和假裝副本是原件。

運行git filter-branch HEAD複製每個可從HEAD到達的提交。我不知道您的存儲庫中有多少次提交,但假設有HEAD可提交150次提交以及20個要刪除的文件。您每次刪除一個文件,因此首先複製150次提交以刪除文件A.然後複製150次提交(即減去文件A的提交)以刪除文件B.然後複製150次提交(即減去A和B)刪除文件C,等等。這意味着您正在製作150 x 20 = 3000份副本。

使用--index-filter(與git rm --cached --ignore-unmatch)將使得3000個拷貝比使用--tree-filter運行快幾個數量級。一次刪除所有文件將製作150份。如果每一項改進都將時間縮短到原來的1/20,那麼兩者合起來就會減少到1/400。

+0

如果在D'和E之間我已經對代碼進行了修改,那麼不會合並A'-B'-C'會實際回滾我對該代碼所做的任何更改嗎? –

+0

因爲它會將以前的版本看作* latest *版本? –

+1

嗯,不,是的。訣竅在於*如何*合併提交。特別是你可能想要運行'git merge --no-commit',而不管任何額外的策略參數。然後你可以操作工作樹,不管你喜歡,'git add'文件產生所需的結果,'git commit'合併。總的來說,我不會特別推薦這樣做,因爲合併首先是這樣,但是你處於一個醜陋的情況,並且處理它的大多數答案都很醜陋;你有你的醜陋選擇X,Y和Z的選擇,我只是添加另一個。 :-) – torek

相關問題