Git之深入解析如何解決.git目錄過大的問題

      網友投稿 2594 2025-03-31

      一、前言

      Git 是一個分布式版本控制軟件,最初目的是為更好地管理 Linux 內核開發,Git 在本地磁盤上就保存著所有有關當前項目的歷史更新,處理速度快。Git 中的絕大多數操作都只需要訪問本地文件和資源,不用實時聯網。

      Git LFS(Large File Storage - ??件存儲)是可以把?樂、圖?、視頻等指定的任意?件存在 Git 倉庫之外,?在 Git 倉庫中??個占?空間 1KB 不到的?本指針來代替的??具。通過把??件存儲在 Git 倉庫之外,可以減? Git 倉庫本身的體積,使克隆 Git 倉庫的速度加快,也使得 Git 不會因為倉庫中充滿??件?損失性能。

      使? Git LFS,在默認情況下,只有當前簽出的 commit 下的 LFS 對象的當前版本會被下載。此外,也可以做配置,只取由 Git LFS 管理的某些特定?件的實際內容,?對于其他由 Git LFS 管理的?件則只保留?件指針,從?節省帶寬,加快克隆倉庫的速度;也可以配置?次獲取??件的最近版本,從?能?便地檢查??件的近期變動。

      二、問題描述

      使用過 Git 的同學都知道,隨著代碼的更新迭代,倉庫的體積越來越大,如果操作和使用都比較恰當的情況下,倉庫體積不會突增的。但是如果使用不恰當的話,那就非常尷尬了,比如下面要說的這種情況,.git 這個隱藏目錄特別大:

      ? du -d 1 -h 680M ./.git 500K ./misc 68K ./docker ... 1.1G .

      1

      2

      3

      4

      5

      6

      雖然 .git 這個隱藏目錄并不算在代碼體積之后,但是拉取代碼的時候,是需要拉下來的,因為里面包含之前的提交記錄等信息,這就會會非常費時費力,因為下載速度變的很慢。

      三、問題分析

      當使用 git add 和 git commit 命令的過程中,Git 不知不覺就會創建出來 blob 文件對象,然后更新 index 索引,再然后創建 tree 對象,最后創建出 commit 對象,這些 commit 對象指向頂層 tree 對象以及先前的 commit 對象。

      而上述創建出來的對象,都以文件的方式保存在 .git/objects 目錄下。所以,當在使用的過程中,提交了一個體積特別大的文件,就會被 Git 追蹤記錄在 .git/objects 文件夾下面。

      此時,如果再次刪除這個體積特別大的文件,其實 Git 只會記錄我們刪除的這個操作,但并不會把文件從 .git 文件夾下面真正的刪除,即 .git 文件夾完全不會變小。

      四、解決方法

      ① 重建倉庫

      重建倉庫的這種做法,算是一種比較一勞永逸且相對而言比較簡單的方式。既然現在的倉庫已經讓我們無法忍受,與其這樣,還不是刪除重建來的爽快。但是,這種做法一般情況下,都是不可行,除非是自己的本地項目。

      ② 刪除大文件

      直接找到 .git 目錄下的大文件,將其刪除掉,之后推送到遠程代碼庫里面。這樣做的前提是,刪除所有其他分支,保留 master 或者 main 分支。

      # 查找大文件 $ git verify-pack -v .git/objects/pack/*.idx 12235d...dewaaaa34 tree 135 137 144088922 a453ab...34se212qz blob 3695898 695871 144734158 ...... # 篩除前五個且保留第一列 $ git verify-pack \ -v .git/objects/pack/*.idx | \ sort -k 3 -n | tail -5 | awk '{print}' 12q626a...23a3 2z32ax1...azfd ...... # 查找出最大的5個文件和對應Commit信息 $ git rev-list --objects --all | \ grep "$(git verify-pack -v .git/objects/pack/*.idx | \ sort -k 3 -n | tail -5 | awk '{print}')" 91266a...sdfa3 data/xxx.pkl 232ax1...acafd data/yyy.pkl ...... # rev-list: 列出Git倉庫中的所有提交記錄 # --objects: 列出該提交涉及的所有文件ID # --all: 所有分支的提交(位于/refs下的所有引用) # verify-pack: 顯示已打包的內容(找大文件)

      1

      Git之深入解析如何解決.git目錄過大的問題

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      18

      19

      20

      21

      22

      23

      24

      25

      26

      # 將其刪除掉 $ git filter-branch \ --force --prune-empty --index-filter \ "git rm -rf --cached --ignore-unmatch YOU-FILE-NAME" \ --tag-name-filter cat -- --all # filter-branch: 重寫Git倉庫中的提交 # --index-filter: 指定后面命令進行刪除 # --all: 所有分支的提交(位于/refs下的所有引用)

      1

      2

      3

      4

      5

      6

      7

      8

      9

      # 強制推送 $ git push --force --all # 徹底清除 $ rm -rf .git/refs/original/ $ git reflog expire --expire=now --all $ git gc --prune=now

      1

      2

      3

      4

      5

      6

      7

      ③ 使用工具清理

      Github 上有一個叫做 git-filter-branch 的工具,就是幫助我們來清理大文件對象的,其使用 Scala 語言進行編寫的,且操作起來也十分方便。只需要簡單幾步,就可以完成我們的需要,最新版需要確保本地的 java 為 Jdk8+。

      # 下載封裝好的jar包 $ wget https://repo1.maven.org/maven2/com/madgag/bfg/1.13.0/bfg-1.13.0.jar # 克隆的時候需要--mirror參數 $ git clone --mirror git://example.com/big-repo.git # 運行BFG來清理存儲庫 $ java -jar bfg.jar --strip-blobs-bigger-than 100M big-repo.git # 去除臟數據 $ cd big-repo.git $ git reflog expire --expire=now --all $ git gc --prune=now --aggressive # 推送上去 # 此推將更新遠程服務器上的所有refs分支 $ git push

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      # 下載封裝好的jar包 $ wget https://repo1.maven.org/maven2/com/madgag/bfg/1.13.0/bfg-1.13.0.jar # 克隆的時候需要--mirror參數 $ git clone --mirror git://example.com/big-repo.git # 運行BFG來清理存儲庫 $ java -jar bfg.jar --strip-blobs-bigger-than 100M big-repo.git # 去除臟數據 $ cd big-repo.git $ git reflog expire --expire=now --all $ git gc --prune=now --aggressive # 推送上去 # 此推將更新遠程服務器上的所有refs分支 $ git push

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      17

      ④ 使用 migrate 命令優化 .git 目錄

      遷移已有的 git 倉庫,使? git lfs 來進行管理,重寫歷史后的提交需執? git commit --force,請確認在本地的操作合適?誤后再進?提交。如有遷移? git lfs 前的倉庫有多份拷?,其他拷?可能需要執? git reset --hard origin/master 來重置其本地的分?,注意執? git reset --hard 命令將會丟失本地的改動。

      # 重寫master分? # 將歷史提交(指的是.git目錄)中的*.zip都?lfs進?管理 $ git lfs migrate import --include-ref=master --include="*.zip" # 重寫所有分?及標簽 # 將歷史提交(指的是.git目錄)中的*.rar,*.zip都?lfs進?管理 $ git lfs migrate import --everything --include="*.rar,*.zip" # 切換后需要把切換之后的本地分支提交到遠程倉庫了,需要手動push更新遠程倉庫中的各個分支 $ git lfs push --force # 切換成功后,GIT倉庫的大小可能并沒有變化 # 主要原因可能是之前的提交還在,因此需要做一些清理工作 # 如果不是歷史記錄非常重要的倉庫,建議不要像上述這么做,而是重新建立一個新的倉庫 $ git reflog expire --expire-unreachable=now --all $ git gc --prune=now

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      五、總結

      比較好的避免上述問題的出現,就是及時使用 lfs 來追蹤、記錄和管理大文件,這樣大文件既不會污染 .git 目錄,也可以更方便的使用:

      # 1.開啟lfs功能 $ git lfs install # 2.追蹤所有后綴名為“.psd”的文件 $ git lfs track "*.iso" # 3.追蹤單個文件 git lfs track "logo.png" # 4.提交存儲信息文件 $ git add .gitattributes # 5.提交并推送到GitHub倉庫 $ git add . $ git commit -m "Add some files" $ git push origin master

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      14

      15

      16

      同時,還有一個方法,就是靈活使用 .gitignore 文件,及時排除倉庫不需要的特殊目錄或者文件,從而不會讓不應該存在的文件,出現在代碼倉庫里面:

      .DS_Store node_modules /dist *.zip *.tar.gz

      1

      2

      3

      4

      5

      6

      Git GitHub

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel公式變文本的方法
      下一篇:Excel VBA中的Open事件
      相關文章
      无码天堂va亚洲va在线va| 亚洲精品无码成人| 国产成人亚洲精品影院| 国产成人综合亚洲一区| 亚洲第一街区偷拍街拍| 亚洲AV综合色区无码一二三区| 国产午夜亚洲精品国产| 亚洲中文字幕一二三四区苍井空| 国产精品亚洲精品观看不卡| 国产精品亚洲精品观看不卡| 国产精品亚洲综合久久| 亚洲日韩看片无码电影| 亚洲国产精品无码久久98| 亚洲AV无码一区二区三区性色| 精品国产日韩亚洲一区在线| 国产亚洲美女精品久久| 亚洲精品动漫人成3d在线| 国产偷国产偷亚洲高清日韩| 亚洲欧洲精品无码AV| 久久精品国产亚洲一区二区| 久久综合日韩亚洲精品色| 亚洲AV电影院在线观看| 久久亚洲sm情趣捆绑调教| 亚洲成人免费网址| 久久夜色精品国产噜噜亚洲a| 亚洲熟女综合一区二区三区| 亚洲AV综合永久无码精品天堂| 国产精品亚洲色婷婷99久久精品| 亚洲国产av一区二区三区| AV在线播放日韩亚洲欧| 亚洲精品无码国产| 亚洲国产二区三区久久| 亚洲色图视频在线观看| 亚洲精品国产国语| 在线观看亚洲专区| 精品国产亚洲一区二区在线观看 | 国产亚洲人成无码网在线观看 | 亚洲Av无码精品色午夜| 亚洲一二成人精品区| 亚洲免费在线视频播放| 亚洲国产AV一区二区三区四区|