Git中對大倉庫的處理實踐
目錄
1.背景
背景章節參考:https://www.oschina.net/translate/how-to-handle-big-repositories-with-git?cmp
兩種大程式碼庫
實際工作中可能會遇到git大倉庫的場景。
如果仔細想想,大概會有兩種導致倉庫大規模增長的原因:
- 專案累積了非常長的歷史(專案成長了很長一段時間並且積累了包袱)。
- 專案包括了巨大的二進位制資產,需要與程式碼一起跟蹤配對。
- 兩者皆有。
1.1處理擁有大量歷史記錄的庫
將一個庫視為大規模庫的界線非常高 - 比如 Linux 核心的最後一個版本記錄了超過 1500 萬行程式碼,但人們仍然願意完整閱讀。
1.1.1淺克隆是簡單的的解決辦法
為了更快、更節省開發者和系統時間也更節約磁碟空間,第一個解決辦法是使用 git 進行淺克隆。通過淺克隆可以只克隆某個庫最後的歷史記錄。怎麼做到?只需要使用 --depth 選項,比如:
git clone --depth depth remote-url
想像一下,如果你的專案庫中積累了 10 年甚至更長時間的歷史記錄 - 比如 JIRA 是我們往 git 遷移的一個 11 年的老庫 - 累積節約的時間非常顯著。完整的克隆 JIRA 有 677 MB,如果包含工作目錄還有另外的 320+ MB,總共超過 47,000 多次提交。通過淺克隆的方式檢出 JIRE 需要 29.5 秒,而檢出完整的歷史記錄則需要 4 分 24 秒。隨著時間地推移及專案二進位制資產的增長,這個差距也會成比例的增長。任何情況下,構建系統都會大大受益於這種技術(指淺克隆)。
1.1.2另一個解決辦法是 filter-branch (過濾分支)
巨大的庫往往存在著大量錯誤的提交或無用的資源,對此,使用 filter-branch 是個很好的解決辦法。這個命令可以根據預先定義的模式對專案歷史進行過濾、整理、修改,甚至跳過一些檔案。它是 git 工具集中的一個非常強大的工具。目前已經有指令碼可以用於識別 git 庫中的大型物件,所以它使用起來非常容易。
使用 filter-branch 的示例:
git filter-branch --tree-filter 'rm -rf /path/to/spurious/asset/folder' HEAD
filter-branch 有一個小小的缺點:一旦使用了 filter-branch,實際上已經重寫了整個專案歷史,因此每次提交的 ID 都會發生變化。這要求每個開發者都要重新克隆更新後的庫。
所以,如果你打算使用 filter-branch 來進行一次清理行動,應該警告你的團隊,計劃一個短期的凍結來進行操作,然後通知大家重新克隆庫。
1.1.3淺克隆的替代者:只克隆一個分支
從 2012 年 4 月釋出的 git 1.7.10 開始,你可以通過只克隆某一個分支來限制歷史記錄的數量,就像這樣:
git clone URL --branch branch_name --single-branch [folder]
對於長期執行分發的分支,或者你在有很多分支的情況下,這個特殊的技巧都非常有用。如果你只有極少數分支,那這個辦法不會帶來顯著的效果。
1.2處理擁有巨大二進位制資產的庫
第二類大型倉庫中的程式碼含有巨大的二進位制資產。遊戲團隊要處理巨大的 3D 模型,Web 開發團隊需要跟蹤影象資產,CAD 團隊可能需要操作和跟蹤二進位制交付物的狀態。所以有各種不同的軟體團隊在使用 git 的過程中會遇到這樣的問題。
git 在處理二進位制資產的時候並不是特別差勁,但它也不會幹得特別好。預設情況下,git 會完整壓縮儲存二進位制資產的所有後續版本,如果你有很多二進位制資產的情況下,這顯然不是最佳方案。
可以通過一些基本的調整來改善情況,比如執行垃圾回收 git gc,或者在 .gitattributes 中對部分二進位制型別進行調整,以使用 delta 方式的提交。
2.倉庫現狀
.
|-- icb1
| |-- image
| | |-- bzImage
| | `-- icb1_zeos_linux_defconfig
| `-- src
| `-- linux-4.13.2
| `-- linux-4.13.2_icb1.tar.gz
|-- imx8qm
| |-- android-8.1
| | |-- image
| | | |-- defconfig
| | | |-- fsl-imx8qm-mek.dtb
| | | `-- Image
| | `-- src
| | `-- kernel_imx_android.tar.gz
| `-- linux-4.9.69
| |-- image
| | |-- defconfig
| | |-- fsl-imx8qm-mek.dtb
| | `-- Image
| `-- src
| `-- kernel-imx8qm.tar.gz
`-- zcu102
|-- image
| |-- defconfig
| |-- Image
| `-- zcu102_phy.dtb
`-- src
`-- linux-2017.3
|-- linux-xlnx-2017.3_video_ea.tar.gz
`-- system-top.dts
從目錄結構可以看出,我們資源庫中存在著大量的二進位制檔案,佔用空間已經達到十幾個G位元組,而且隨著專案的增加,倉庫必然更大,幾百個G,甚至上T。隨著專案的演進,資源庫中會存入其他資料,如文件、指令碼等輕量級檔案。如果為了看某些文件而將整個倉庫克隆下來,顯然是不划算的。
3.倉庫改造
目前倉庫所有二進位制程式碼都處於master分支。為了解決上面描述的問題,我們可以引入GIT的分支管理。
我們的構想是:輕量化master分支,對其他資源如文件、指令碼、原始碼、映象分別建立不同的分支來進行管理。Git 克隆時只克隆master分支,然後對需要的分支進行單獨處理。這樣,既節省了克隆時間,又節省了儲存空間。
下面,就對目前倉庫進行改造。
3.1第一步:先建立一個VM分支,並推送至伺服器
因為目前倉庫只有原始碼映象檔案,所以,只需要先把框架搭建起來;後面要增加文件、指令碼等就比較方便。
git branch VM git checkout VM touch readme git add readme git commit -m “VM branch first commit” git push origin VM:VM |
3.2第二步:輕量化master分支
目前採取的措施很暴力,直接清空master分支,讓其不儲存任何資源。這裡就會用到“背景”部分提到的核武器級選項“filter-branch”
git checkout master git filter-branch --tree-filter 'rm -f passwords.txt' HEAD git gc --aggressive --prune=now git push --force origin master |
--tree-filter 選項在檢出專案的每一個提交後執行指定的命令然後重新提交結果。在本例中,你從每一個快照中移除了一個叫作 passwords.txt 的檔案,無論它是否存在。
我們這裡可以使用:git filter-branch --tree-filter 'rm -rf *' HEAD命令,直接刪除所有。
3.3第三步:刪除倉庫目錄,重新克隆
因為,前面利用 filter-branch修改了整個倉庫的檔案及提交記錄,如前面“背景”部分提到的,你需要重新克隆工程,才能體驗到“.git資料夾”減小的快感。
git clone [email protected] |
這樣,架構已經搭建好了,如果後面要新增新的分支,就可以直接操作了。在新建分支時,預設會保留master的提交記錄,如果你不想這樣,可以用下面的命令:
git branch newbranch git checkout --orphan newbranch |
--orphan引數可以讓你去掉歷史遺留提交記錄
4.倉庫使用
經歷了上面的倉庫改造後,如果新使用者的你直接克隆整個倉庫,仍然會將倉庫包含的所有分支資訊的.git資料夾下載下來。雖然其是壓縮後的資料檔案,但當二進位制檔案很多時,.git資料夾也會非常之大。
所以,我們可以只克隆倉庫的master分支下來(幾十KB),它包含了本地倉庫與遠端倉庫的聯絡。然後,再建立一個本地分支來跟蹤遠端你需要的分支。這樣,你就可以在本地只保留需要的分支的資料檔案。時間和空間都可以節省。命令示例入下:
//只檢出master分支 git clone [email protected]:/home/gaojianyun/test.git --branch master --single-branch git branch test //建立本地分支 git checkout test //切換到本地分支 git pull origin vm //拉取遠端需要的分支 //下面是需要提交更改步驟 git push --set-upstream origin test:vm //首次建立聯絡 git push origin //首次過後,就可以直接push了 |
相關推薦
Git中對大倉庫的處理實踐
目錄 1.背景 1.背景 背景章節參考:https://www.oschina.net/translate/how-to-handle-big-repositories-with-git?cmp 兩種大程式碼庫 實際工作中
MapReuce中對大數據處理最合適的數據格式是什麽?
reduce 版本支持 詳細 復雜 設置 解壓縮 表示 字符串 保存 本節作為《Hadoop從入門到精通》大型專題的第三章第二節將教大家如何在Mapreduce中使用XML和JSON兩大常見格式,並分析比較最適合Mapreduce大數據處理的數據格式。 在本章的第一章節介紹
Cesium中對geojson的處理
最近關注到cesium對json處理,有點小收穫,記錄下來,有不對的請指正。 Cesium讀取geojson cesium支援topojson,GEOjson和普通的json格式,方法可以共用 一.topojson <body> <div id="cesiu
Spring Boot中對自然語言處理工具包hanlp的呼叫詳解
概 述 HanLP 是基於 Java開發的 NLP工具包,由一系列模型與演算法組成,目標是普及自然語言處理在生產環境中的應用。而且 HanLP具備功能完善、效能高效、架構清晰、語料時新、可自定義的特點,因此十分好上手,本文就結合 Spring Boot來將 HanLP用起來!
9 sql 中對日期的處理
https://blog.csdn.net/fighting_tl/article/details/73838692 1 查詢當天的使用量 select count(*) count from t_user where date(creat
Git撤銷對遠端倉庫的push提交
1. 執行 git log檢視日誌,獲取需要回退的版本號 2. 執行 git reset –soft <版本號> ,如 git reset -soft 4f5e9a90edeadcc45d85f43bd861a837fa7ce4c7 ,重置至指定版本的提交,達到撤銷提交的目的 然後執行 gi
JDBC(6)mysql中的大資料處理
免費錄播jdbc視訊 JDBC操作 驅動可以不註冊 * 可以省略 Class.forName(driver); (高版本) * 原因:mysql-connector-java-5.1.22-bin.ja
mysql 資料庫實際應用中的大資料處理
某年某月,我接到公司的任務,要搭建一個遊戲平臺系統,管理旗下所有遊戲的玩家賬戶資料。起初拿到任務後,想了想。那麼這個系統就是一個註冊,一個登陸就ok了。 於是有了下面的資料庫設計。tbl_account. 表【主鍵ID,使用者名稱,密碼,註冊時間,……】 業務邏輯開發完成,
iOS中對時間的處理(三)——各時區時間相互轉化
手機本地系統時間轉化為指定時區時間 NSArray *timeZoneNames = [NSTimeZone knownTimeZoneNames]; NSLog(@"array_%@",timeZoneNames); NSString *startTim
C程式中對時間的處理——time庫函式詳解
功 能:將時間格式化,或者說:格式化一個時間字串。我們可以使用strftime()函式將時間格式化為我們想要的格式。 原 型:size_t strftime(char *strDest,size_t maxsize,const char *format,const struct tm *timept
LR中對字串的處理
Action() { char * str="testroad"; char * str2 = "tid=231&fid=322"; fun_Factorial(); lr_output_message("%s",fun_Reve
Oracle中對時間間隔處理成幾天幾小時幾分鐘幾秒
oracle中將datetime欄位的間隔處理顯示成幾天幾小時幾分鐘幾秒進行顯示 --numtodsinterval(<x>,<c>) ,x是一個數字,c是一個字串, 表明x的單位,這個函式把x轉為interval day to second資
OSG學習筆記15-OSG中對事件的處理
看了王銳大大的書,我感覺OSG中對事件的處理主要是由以下幾塊組成的: 1、事件介面卡 GUIEventAdapter 這個類是作為系統互動事件和OSG互動事件的適配介面。這一句話還不是很理解。 原始碼文件裡對於這個類的定義是:事件類,儲存鍵盤、滑鼠和視窗事件。 公有型別包括
jupyter 中對圖片基本處理操作
eye()的使用方法 import numpy as np a = np.eye(2,3) #隨機生成一個2*3的矩陣 #a = np.eye(3) #隨機生成一個3*3的矩陣 print (a) 在jupyter notebook中顯示資料夾中的圖片 impor
linux中對大檔案切割
切割一般分為按大小分割和按一定行數切割。按檔案行數:split -l 1000 test.data aaa還可以指定被切割後的檔名split -l 1000 -d -a 3 aaa_ -a, --suffix-length=N指定字尾長度為N (預設為2) -b, --
Git中刪除大檔案或清除汙染檔案
有時候,如果gitignore沒有寫好,或者自己在某些目錄下放入了一個大檔案,而同時又已經commit或者push到倉庫裡了,很容易導致倉庫容量越來越大,同時你本地的.git裡的pack檔案也會大得一塌糊塗 當你已經把專案工程的大小縮減到滿意的地步,還要注意一點,在
QT中對XML的處理
QT自帶例子: C:\Qt\Qt5.5.1\Examples\Qt-5.5\widgets\itemviews\simpledommodel\simpledommodel.pro C:\Qt\Qt5.5.1\Examples\Qt-5.5\xml\dombookmarks\
layui 表單中對日期的處理
參考文章:https://blog.csdn.net/qq_26173219/article/details/79709644再使用layui 後臺傳遞頁面Date型別資料時,發現layui前臺接收的是"createTime":{ "date":
symfony2中對異常的處理,個人總結
習慣了之前的出現錯誤,就立即解決的方式。現在在用symfony的用法,發現原來自己一直錯過了一個東西:Exception 現在講講symfony2中如何處理錯誤 1.首先自己在src/AppBundle下建立了一個Exception的資料夾, BaseException.p
Git 倉庫中刪除大檔案的歷史提交記錄
剛接觸這東西,會使用GitHub for windows 之後,感覺挺好用的。 不過最近發現,程式碼庫已經有90M大小了。想一想,除了把ttf字型檔案提交了之外,圖片素材,和編譯後的class檔案都提交了。 網上找一些方法,刪除歷史記錄。綜合一下,總算成功了。 官