一個讓 git clone 提速幾十倍的小技巧

這是我參與更文挑戰的第2天,活動詳情查看: 更文挑戰git

不知道你們有沒有遇到比較大的項目,git clone 很慢很慢,甚至會失敗的那種。你們會怎麼處理的呢?github

可能會考慮換一個下載源,可能會經過一些手段提升網速,可是若是這些都試過了仍是比較慢呢?typescript

今天我就遇到了這個問題,我須要把 typescript 代碼從 gitlab 下載下來,可是速度特別慢:shell

git clone https://github.com/microsoft/TypeScript ts
複製代碼

等了好久仍是沒下載完,因而我加了一個參數:markdown

git clone https://github.com/microsoft/TypeScript --depth=1 ts
複製代碼

這樣速度提升了幾十倍,瞬間下載完了。gitlab

加上 --depth 會只下載一個 commit,因此內容少了不少,速度也就上去了。post

並且下載下來的內容是能夠繼續提交新的 commit、建立新的分支的。不影響後續開發,只是不能切換到歷史 commit 和歷史分支。測試

我用個人一個項目測試過,我首先下載了一個 commit:spa

而後作一下改動,以後 git add、commit、push,可以正常提交:指針

建立新分支也能正常提交。惟一的缺點就是不能切換到歷史 commit 和歷史分支。

在一些場景下仍是比較有用的:當須要切換到歷史分支的時候也能夠計算須要幾個 commit,而後再指定 depth,這樣也能夠提升速度。

你們有沒有想過,這樣能行的原理是什麼?

git 原理

git 是經過一些對象來保存信息的:

  • glob 對象存儲文件內容
  • tree 對象存儲文件路徑
  • commit 對象存儲 commit 信息,關聯 tree

以一個 commit 爲入口,關聯的全部的 tree 和 blob,就是這個 commit 的內容。

commit 之間相互關聯,而 head、branch、tag 等是指向具體 commit 的指針。能夠在 .git/refs 下看到。這樣就基於 commit 實現了分支、tag 等概念。

git 就是經過這三個對象來實現的版本管理和分支切換的功能,全部 objects 能夠在 .git/objects 下看到。

這就是 git 的原理。

主要理解 blob、tree、commit 這三個 object,還有 head、tag、branch、remote 等 ref。

能下載單個 commit 的原理

咱們知道了 git 是經過某一個 commit 作爲入口來關聯全部的 object,那若是咱們不須要歷史天然就能夠只下載一個 commit。

這樣依然基於那個 commit 建立新的 commit,關聯新的 blob、tree 等。可是歷史的 commit、tree、blob 由於都沒有下載下來因此沒法切回去,相應的 tag、branch 等指針也不行。這就是咱們下載了單個 commit 卻依然能夠建立新的分支、commit 等的原理。

總結

遇到大的 git 項目的時候,能夠經過添加 --depth 參數使得速度極大提高,歷史 commit 越多,下載速度提高越大。

並且下載下來的項目依然能夠進行後續開發,能夠建立新的 commit 和新的分支、tag,只是不能切換到歷史 commit、分支、tag。

咱們梳理了 git 的原理:經過 tree、blob、commit 這三個 object 來存儲文件和提交信息,經過 commit 之間的關聯來實現分支、標籤等功能。commit 是入口,關聯全部的 tree 和 blob。

咱們下載了一個 commit,就是下載了他關聯的全部 tree、blob,還有一些 refs (包括tag、branch 等),這就是 --depth 的原理。

但願你們在不須要切換到歷史 commit 和分支的場景下能夠用這個技巧來提高大項目的 git clone 速度。

相關文章
相關標籤/搜索