中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Git 內(nèi)部原理之 Git 對象存儲

2018-07-02    來源:importnew

容器云強勢上線!快速搭建集群,上萬Linux鏡像隨意使用

在Git內(nèi)部原理之Git對象哈希中,講解了Git對象hash的原理,接下來的這篇文章講一講Git對象如何存儲。

原理

數(shù)據(jù)對象、樹對象和提交對象都是存儲在.git/objects目錄下,目錄的結(jié)構(gòu)如下:

.git
|-- objects
    |-- 01
    |   |-- 55eb4229851634a0f03eb265b69f5a2d56f341
    |-- 1f
    |   |-- 7a7a472abf3dd9643fd615f6da379c4acb3e3a
    |-- 83
        |-- baae61804e65cc73a7201a7252750c76066a30

從上面的目錄結(jié)構(gòu)可以看出,Git對象的40位hash分為兩部分:頭兩位作為文件夾,后38位作為對象文件名。所以一個Git對象的存儲路徑規(guī)則為:

.git/objects/hash[0, 2]/hash[2, 40]

這里就產(chǎn)生了一個疑問:為什么Git要這么設(shè)計目錄結(jié)構(gòu),而不直接用Git對象的40位hash作為文件名?原因是有兩點:

1.有些文件系統(tǒng)對目錄下的文件數(shù)量有限制。例如,F(xiàn)AT32限制單目錄下的最大文件數(shù)量是65535個,如果使用U盤拷貝Git文件就可能出現(xiàn)問題。
2.有些文件系統(tǒng)訪問文件是一個線性查找的過程,目錄下的文件越多,訪問越慢。

在Git內(nèi)部原理之Git對象哈希中,我們知道Git對象會在原內(nèi)容前加個一個頭部:

store = header + content

Git對象在存儲前,會使用zlib的deflate算法進行壓縮,即簡要描述為:

zlib_store = zlib.deflate(store)

壓縮后的zlib_store按照Git對象的路徑規(guī)則存儲到.git/objects目錄下。

總結(jié)下Git對象存儲的算法步驟:

  1. 計算content長度,構(gòu)造header;
  2. 將header添加到content前面,構(gòu)造Git對象;
  3. 使用sha1算法計算Git對象的40位hash碼;
  4. 使用zlib的deflate算法壓縮Git對象;
  5. 將壓縮后的Git對象存儲到.git/objects/hash[0, 2]/hash[2, 40]路徑下;

Nodejs實現(xiàn)

接下來,我們使用Nodejs來實現(xiàn)git hash-object -w的功能,即計算Git對象的hash值并存儲到Git文件系統(tǒng)中:

const fs = require('fs')
const crypto = require('crypto')
const zlib = require('zlib')
function gitHashObject(content, type) {
  // 構(gòu)造header
  const header = `${type} ${Buffer.from(content).length}\0`
  // 構(gòu)造Git對象
  const store = Buffer.concat([Buffer.from(header), Buffer.from(content)])
  // 計算hash
  const sha1 = crypto.createHash('sha1')
  sha1.update(store)
  const hash = sha1.digest('hex')
  // 壓縮Git對象
  const zlib_store = zlib.deflateSync(store)
  // 存儲Git對象
  fs.mkdirSync(`.git/objects/${hash.substring(0, 2)}`)
  fs.writeFileSync(`.git/objects/${hash.substring(0, 2)}/${hash.substring(2, 40)}`, zlib_store)
  console.log(hash)
}
// 調(diào)用入口
gitHashObject(process.argv[2], process.argv[3])

最后,測試下能否正確存儲Git對象:

$ node index.js 'hello, world' blob
8c01d89ae06311834ee4b1fab2f0414d35f01102
$ git cat-file -p 8c01d89ae06311834ee4b1fab2f0414d35f01102
hello, world

由此可見,我們生成了一個合法的Git數(shù)據(jù)對象,證明算法是正確的。

標簽:

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:深入 Spring Boot :實現(xiàn)對 Fat Jar jsp 的支持

下一篇:RocketMQ 源碼學(xué)習(xí) 3 :Remoting 模塊