[英]Is it possible to slim a .git repository without rewriting history?
由於二進制測試文件和java .jar
文件的歷史包含,我們有許多git
存儲庫已經增長到難以管理的大小。
我們正要進行git filter-branch
這些存儲庫的練習,在它們被使用的任何地方重新克隆它們(從幾十個到幾百個部署,取決於repo)並且考慮到重寫歷史的問題我想知道如果可能有任何其他解決方案。
理想情況下,我想在不重寫每個存儲庫的歷史記錄的情況下將問題文件外部化。 理論上這應該是可能的,因為你檢查相同的文件,具有相同的大小和相同的哈希值,只是從不同的地方(遠程而不是本地對象存儲)獲取它們。 到目前為止,我找到的任何潛在解決方案似乎都不允許我這樣做。
從git-annex開始,我能找到解決問題的最接近的方法是如何追溯性地附加一個已經存在於git倉庫中的文件 ,但就像刪除大文件一樣,這需要重新編寫歷史記錄以進行轉換原來的git add
到git annex add
。
從那里開始,我開始查看git-annex不是所列出的其他項目,所以我檢查了git-bigfiles , git-media和git-fat 。 不幸的是,我們不能使用的混帳bigfiles叉git
,因為我們是一個Eclipse 店和使用的混合物git
和例如:It 。 它看起來不像git-media或git-fat也可以做我想要的,因為雖然你可以用外部等價物替換現有的大文件,但你仍然需要重寫歷史記錄以刪除已經存在的大文件一直致力於。
那么,是否可以在不重寫歷史記錄的情況下縮小.git存儲庫,或者我們是否應該回到使用git filter-branch
和一大堆重新部署的計划?
順便說一句,相信這應該是可能的,但可能與git
當前淺層克隆實現的限制相同。
Git已經為同一個blob支持多個可能的位置,因為任何給定的blob都可以在松散的對象存儲 ( .git/objects
)或包文件 (.git / objects)中,所以理論上你只需要像git-annex
這樣的東西在這個級別而不是更高級別(例如,如果你願意,可以按需下載遠程blob的概念)。 不幸的是,我找不到任何人已經實施甚至建議這樣的事情。
有點。 您可以使用Git的替換功能來預留大膨脹歷史記錄,以便僅在需要時下載。 它就像一個淺層克隆,但沒有淺層克隆的限制。
這個想法是你通過創建一個新的root提交來重新啟動分支,然后挑選舊分支的提示。 通常你會以這種方式丟失所有的歷史記錄(這也意味着你不必克隆那些大的.jar
文件),但如果需要歷史記錄,你可以獲取歷史提交並使用git replace
將它們無縫地拼接回來。
請參閱Scott Chacon的優秀博客文章 ,了解詳細解釋和演練。
這種方法的優點:
.jars
和一切,你仍然可以。 這種方法的缺點:
這種方法仍然存在一些與重寫歷史相同的問題。 例如,如果您的新存儲庫如下所示:
* modify bar (master) | * modify foo <--replace--> * modify foo (historical/master) | | * instructions * remove all of the big .jar files | * add another jar | * modify a jar |
並且有人在他們合並的歷史分支中有一個舊分支:
* merge feature xyz into master (master) |\\__________________________ | \\ * modify bar * add feature xyz | | * modify foo <--replace--> * modify foo (historical/master) | | * instructions * remove all of the big .jar files | * add another jar | * modify a jar |
然后,大的歷史提交將重新出現在您的主存儲庫中,並且您將回到您開始的位置。 請注意,這並不比重寫歷史記錄更糟糕 - 有人可能會在預重寫提交中意外合並。
這可以通過在共享存儲庫中添加update
掛鈎來減輕任何將重新引入歷史根提交的推送來緩解。
不,這是不可能的 - 你將不得不重寫歷史。 但是這里有一些指示:
git filter-branch
更容易使用。 你不需要再次克隆! 只需運行這些命令而不是git pull
,你就可以了(用你的遠程和分支替換origin
和master
):
git fetch origin git reset --hard origin/master
但請注意,與git pull
不同,您將丟失尚未推送到服務器的所有本地更改。
git pull
, git merge
和git rebase
(以及git rebase --onto
)這樣做,它git rebase --onto
幫助。 然后讓每個人都參與一個關於如何處理這種重寫情況的快速培訓(5-10分鍾就足夠了,基本的注意事項和注意事項)。 git filter-branch
本身不會造成任何傷害,但會導致許多標准工作流程造成傷害。 如果人們沒有采取相應行動並合並舊歷史,如果您沒有及時發現,可能只需要重新編寫歷史記錄。 我不知道一個可以避免重寫歷史的解決方案。
在這種情況下,使用BFG-repo清潔工具清潔rpeo是最簡單的解決方案( git filter-branch
更容易)。
老實說,我想不出辦法做到這一點。 如果你考慮Git“承諾”你作為一個用戶,關於數據完整性,我想不出你可以從存儲庫中刪除文件並保持相同的哈希的方法。 換句話說,如果你問的是可能的,那么Git的可靠性會低得多......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.