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

Git 內(nèi)部原理之 Git 對(duì)象存儲(chǔ)

2018-07-02    來源:importnew

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬Linux鏡像隨意使用

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

原理

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

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

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

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

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

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

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

store = header + content

Git對(duì)象在存儲(chǔ)前,會(huì)使用zlib的deflate算法進(jìn)行壓縮,即簡(jiǎn)要描述為:

zlib_store = zlib.deflate(store)

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

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

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

Nodejs實(shí)現(xiàn)

接下來,我們使用Nodejs來實(shí)現(xiàn)git hash-object -w的功能,即計(jì)算Git對(duì)象的hash值并存儲(chǔ)到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對(duì)象
  const store = Buffer.concat([Buffer.from(header), Buffer.from(content)])
  // 計(jì)算hash
  const sha1 = crypto.createHash('sha1')
  sha1.update(store)
  const hash = sha1.digest('hex')
  // 壓縮Git對(duì)象
  const zlib_store = zlib.deflateSync(store)
  // 存儲(chǔ)Git對(duì)象
  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])

最后,測(cè)試下能否正確存儲(chǔ)Git對(duì)象:

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

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

標(biāo)簽:

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

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

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