這是我參與更文挑戰的第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 是經過一些對象來保存信息的:
以一個 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。
咱們知道了 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 速度。