1. 程式人生 > >Git中對大倉庫的處理實踐

Git中對大倉庫的處理實踐

目錄

1.背景

1.背景

背景章節參考:https://www.oschina.net/translate/how-to-handle-big-repositories-with-git?cmp

兩種大程式碼庫

實際工作中可能會遇到git大倉庫的場景。

如果仔細想想,大概會有兩種導致倉庫大規模增長的原因:

  1. 專案累積了非常長的歷史(專案成長了很長一段時間並且積累了包袱)。
  2. 專案包括了巨大的二進位制資產,需要與程式碼一起跟蹤配對。
  3. 兩者皆有。

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大數據處理的數據格式。 在本章的第一章節介紹

Cesiumgeojson的處理

最近關注到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檔案也會大得一塌糊塗 當你已經把專案工程的大小縮減到滿意的地步,還要注意一點,在

QTXML的處理

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檔案都提交了。 網上找一些方法,刪除歷史記錄。綜合一下,總算成功了。 官