底層命令與文件結(jié)構(gòu)

Git 實(shí)質(zhì)

參考

Git 是一個(gè)內(nèi)容尋址文件系統(tǒng)忘苛。 這意味著蝉娜,Git 的 核心部分是一個(gè)簡(jiǎn)單的鍵值對(duì)數(shù)據(jù)庫(kù)。 你可以向該數(shù)據(jù)庫(kù)插入任意類型的內(nèi)容扎唾,它會(huì)返回一個(gè)鍵值召川,通過(guò)該鍵值可以在任意時(shí)刻再次檢索(retrieve)該內(nèi)容。


底層命令

涉及到的底層命令有:

命令 解釋
cat-file 獲取指定 Git 對(duì)象的信息
ls-files 顯示暫存區(qū)的信息
ls-tree 顯示指定結(jié)點(diǎn)的 tree 對(duì)象
hash-object 用于計(jì)算文件的 sha-1 值
update-index 更新暫存區(qū)
write-tree 將暫存區(qū)中的文件寫成 tree 對(duì)象
read-tree 把樹(shù)對(duì)象讀入暫存區(qū)
commit-tree 根據(jù)指定的樹(shù)對(duì)象創(chuàng)建一個(gè)提交對(duì)象
rev-parse 解析分支名或標(biāo)簽名對(duì)應(yīng)的提交對(duì)象的 sha-1 值

Git 所做的實(shí)質(zhì)工作 —— 將被改寫的文件保存為數(shù)據(jù)對(duì)象(hash-object)胸遇,更新暫存區(qū) ( update-index )荧呐,記錄樹(shù)對(duì)象(write-tree),最后創(chuàng)建一個(gè)指明了頂層樹(shù)對(duì)象和父提交的提交對(duì)象(commit-tree)纸镊。


ls-tree

用于顯示指定結(jié)點(diǎn)對(duì)應(yīng)的 tree 對(duì)象中的內(nèi)容倍阐。

它會(huì)展示所有的文件(即 blob 對(duì)象)。

$ git ls-tree -r HEAD
100644 blob 34f7ae03cc475d78515719c5b6f8c34e46002f7f    aa
100644 blob c93ab02d540e388e1b83e23bbd8b49cb97c4b4ce    bb
100644 blob 837df2b7ed69104790e279524d51880324064492    cc
100644 blob 9b5cf45dcf51d69998fc7cdab86ea8afb2905047    cid.java
100644 blob 79f6e4824f9578f237633353e8d6939c8bffcca1    dd.txt
100644 blob 7f1021754129446ecef3fecab549015ccbe5e59f    ee
100644 blob f0e0aa843620d42bb1e72f4949001d0ca4173dc1    i/i.txt
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    i/ii/xx.txt
100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391    new
100644 blob 59f2c499c12c1385dd0ff1131a50820e7f6a618c    test.html
100644 blob d6459e005434a49a66a3ddec92279a86160ad71f    xxx.xxx

從輸出可以看出逗威,其中有幾個(gè)文件是子目錄下的文件峰搪,它也會(huì)直接列出來(lái)。


rev-parse

解析分支凯旭、標(biāo)簽等指向的提交對(duì)象的 sha-1 值概耻。

如:

$     git rev-parse master
9b335a39f65dff232f239c08baeeb9f7d27f193a
$     git tag t1
$     git rev-parse t1
9b335a39f65dff232f239c08baeeb9f7d27f193a
$     git rev-parse HEAD
9b335a39f65dff232f239c08baeeb9f7d27f193a

master 與 HEAD 為分支名, t1 為標(biāo)簽名罐呼。


ls-files

用于獲取暫存區(qū)的信息鞠柄。

其常用的幾個(gè)選項(xiàng)有:

-c : 在輸出中顯示暫存的文件。默認(rèn)值嫉柴。此選項(xiàng)只會(huì)輸出文件名厌杜。

--stage : 顯示文件的詳細(xì)信息。包括文件名计螺,sha-1 值夯尽,文件模式等。

$ git ls-files --stage
100644 6b20baa0a072d5c9578e024942c6ce1d42cf5a2a  0          a.txt
100644 24e27b2a30edadba619d26e2d3662ec307cdddb2 0   test.html
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0   xx

上述命令顯示當(dāng)前暫存區(qū)中暫存的有三個(gè)文件登馒。


hash-object 命令

計(jì)算文件的 sha-1 值呐萌,并可選地根據(jù)該文件創(chuàng)建一個(gè) blob 對(duì)象。

注意:該命令只適用于文件谊娇,不能用于目錄肺孤。

選項(xiàng) 解釋
-w 不加該選項(xiàng)則不會(huì)生成 blob 對(duì)象,反之則會(huì)生成
--stdin hash-object 命令會(huì)從標(biāo)準(zhǔn)輸入讀取內(nèi)容
-- <path> 指定 hash-object 操作的文件的路徑

注意:如果使用 --stdin 選項(xiàng)济欢,就需要指定文件路徑赠堵。

如:

$ find .git/objects/ -type f
$ git hash-object -- ../appid.txt 
a5a06de3b66ee3a609def184e78873c99d6b1221
$ find .git/objects/ -type f
$ git hash-object -w -- ../appid.txt 
a5a06de3b66ee3a609def184e78873c99d6b1221
$ find .git/objects/ -type f
.git/objects//a5/a06de3b66ee3a609def184e78873c99d6b1221

find 命令用于查找指定目錄( .git/objects )目錄下的所有文件( 通過(guò) -type f 限定 )。

從上可以看出法褥,起初 objects 目錄下并沒(méi)有文件茫叭。hash-object 不加 -w 操作后,目錄下依舊沒(méi)有文件半等,只不過(guò)輸出了指定文件的 sha-1 值揍愁。

加上 -w 選項(xiàng)后呐萨,objects 目錄下多了一個(gè)父目錄為 a5 的文件。Git 會(huì)截取 sha-1 值的前兩個(gè)字符生成目錄名莽囤,將剩余的部分做為文件名谬擦。因此,objects 目錄下會(huì)有一個(gè) a5 目錄朽缎。


cat-file

獲取指定的 Git 對(duì)象的內(nèi)容等信息惨远。

其常用的選項(xiàng)如下:

選項(xiàng) 解釋
-p 后跟 sha-1 值,則 cat-file 會(huì)返回該 sha-1 值的內(nèi)容
-t 獲取指定對(duì)象的類型
-s 獲取指定對(duì)象的大小

在使用時(shí)话肖,可以通過(guò) > <path> 后綴北秽,將 cat-file 的輸出內(nèi)容輸出到指定的文件中。如 git cat-file -p bf43b62de7d99fa2c427dcc82257d81431ba816f > xxx.xxx 就會(huì)將內(nèi)容輸出到同目錄下的 xxx.xxx 文件中最筒。

如 -p 選項(xiàng)的使用:

$ git cat-file -p 9daeafb9864cf43055ae93beb0afd6c7d144bfa4
test

其中 test 為該對(duì)象的內(nèi)容贺氓。

如 -t 選項(xiàng)的使用:

$ git cat-file -t ee1a8365ec2baa3e5a97cb6e44d8d8b5c553fb30
blob

$ git cat-file -t 8bdb01d84c5ad6456acb4d8df8d82a0db5214972
tree

$ git cat-file -t bf43b62de7d99fa2c427dcc82257d81431ba816f
commit

Git 中一共有三種對(duì)象 :commit , tree 與 blob ,所以 -t 只會(huì)輸出這三個(gè)值中的一個(gè)床蜘。


update-index

該選項(xiàng)用于更新暫存區(qū)辙培。git addgit rm 等命令都是對(duì)該選項(xiàng)的封裝。

其常用的選項(xiàng)有:

選項(xiàng) 解釋
<無(wú)> 更新已暫存的文件
--add 將未跟蹤的文件添加到暫存區(qū)中
--cacheinfo 將已保存到本地倉(cāng)庫(kù)的文件加入到暫存區(qū)中
--remove 將已刪除的文件從暫存區(qū)中移除

各個(gè)選項(xiàng)具體說(shuō)明如下:

  1. --add : 如果文件從來(lái)沒(méi)有添加到暫存區(qū)中悄泥,該選項(xiàng)表示將文件第一次添加到暫存區(qū)中虏冻。

    $ git ls-files --stag
    100644 6b20baa0a072d5c9578e024942c6ce1d42cf5a2a 0   a.txt
    
    $ git hash-object yy
    e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
    $ git update-index --add yy
    $ git ls-files --stage
    100644 6b20baa0a072d5c9578e024942c6ce1d42cf5a2a 0   a.txt
    100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0   yy
    

    初始時(shí)肤粱,暫存區(qū)中只有一個(gè) a.txt 文件弹囚。使用 git update-index --add 命令后,暫存區(qū)中多了一個(gè) yy 文件领曼,并且 yy 文件與 update-index 指定的文件的 sha-1 值相同鸥鹉,所以該命令可以將指定的文件添加到暫存區(qū)中。

    再查看 .git/objects 目錄下庶骄,可以發(fā)現(xiàn)多了一個(gè)文件(即 yy 文件)毁渗。

  2. --cacheinfo:如果要保存的文件已位于 git 倉(cāng)庫(kù)中,需要使用該選項(xiàng)单刁。

    $ vim yy 
    $ git hash-object -w -- yy 
    9be86ae7054f7c477afabe3d971046032851b574
    
    $ git update-index --cacheinfo 100644 9be86ae7054f7c477afabe3d971046032851b574 yy 
    

    首先修改 yy 文件灸异,并通過(guò) hash-object 將文件存儲(chǔ)到 git 目錄中。所以更新暫存區(qū)時(shí)不需要 --add 選項(xiàng)羔飞。

    在使用 --cacheinfo 修改暫存區(qū)時(shí)肺樟,指定了文件的 sha-1 值,同時(shí)也指定了文件模式為 100644(即普通文件)逻淌。

  3. --remove:將指定的文件從索引中刪除么伯,該文件必須已經(jīng)從工作目錄中刪除

    $ git ls-files --stage
    100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0   xx
    100644 9be86ae7054f7c477afabe3d971046032851b574 0   yy
    
    $ rm xx 
    $ git update-index --remove -- xx
    $ git ls-files --stage
    100644 9be86ae7054f7c477afabe3d971046032851b574 0   yy
    
    $ git update-index --remove -- yy 
    $ git ls-files --stage
    100644 9be86ae7054f7c477afabe3d971046032851b574 0   yy
    

    不刪除文件直接使用 --remove 選項(xiàng)時(shí)卡儒,并不會(huì)刪除相應(yīng)的記錄(如上例中的 yy 文件)田柔。


write-tree

將暫存區(qū)內(nèi)容寫入一個(gè)樹(shù)對(duì)象俐巴。

通過(guò) update-index 更新暫存區(qū)后,基本的文件并沒(méi)有生成成 tree 對(duì)象硬爆。而 write-tree 可以根據(jù)暫存區(qū)生成一個(gè)樹(shù)對(duì)象欣舵。

$ git write-tree
348eb10c8ce3e5a4561a38aa7e76e61013e153e1

$ git cat-file -t 348eb10c8ce3e5a4561a38aa7e76e61013e153e1
tree

read-tree

將指定的樹(shù)對(duì)象讀入到暫存區(qū)中。

通過(guò) --prefix=name 指定讀入的樹(shù)對(duì)象的名字摆屯。

首先將一個(gè)樹(shù)對(duì)象讀入暫存區(qū)中邻遏,然后通過(guò) write-tree 將暫存區(qū)中的內(nèi)容寫入一個(gè)樹(shù)對(duì)象中。則新生成的樹(shù)對(duì)象會(huì)包含一個(gè)指向通過(guò) read-tree 讀入的樹(shù)對(duì)象的指針虐骑。

$ git read-tree --prefix=namep 348eb10c8ce3e5a4561a38aa7e76e61013e153e1

執(zhí)行上述命令后准验,如果將當(dāng)前暫存區(qū)生成一個(gè) tree 對(duì)象后,該對(duì)象會(huì)包含一個(gè)名為 namep 的指針廷没,它指向的是通過(guò) read-tree 讀入的樹(shù)對(duì)象糊饱。


commit-tree

根據(jù)指定的樹(shù)對(duì)象創(chuàng)建一個(gè)提交對(duì)象。

通過(guò) -p sha-1 指定當(dāng)前對(duì)象的父對(duì)象

$ echo "first commit" | git commit-tree 2aabf73883cc35cef05f3c7919274da2aaebf674
cbc41af8ae9347c21299005f40ce998e58ab357e

$ echo "third" | git commit-tree fa197580163fc711a76726db35488f433968699c -p cbc41af8ae9347c21299005f40ce998e58ab357e

7e0792c1e2b634b4721edc6e3ff6f206d18298a2

echo 指定的是本次提交的說(shuō)明颠黎。

上述命令新建了兩個(gè) commit 對(duì)象另锋,并將第二個(gè) commit 對(duì)象的父結(jié)點(diǎn)指向第一個(gè)對(duì)象。

當(dāng)在第二個(gè) commit 對(duì)象處建立分支后狭归,運(yùn)行 git log 命令夭坪,可以發(fā)現(xiàn)有兩條提交記錄。


目錄

Git 有幾個(gè)非常重要的文件:

  1. objects 目錄存儲(chǔ)所有數(shù)據(jù)內(nèi)容过椎;

  2. refs 目錄存儲(chǔ)指向數(shù)據(jù)(分支)的提交對(duì)象的指針室梅。

    1. refs/heads 存儲(chǔ)的是當(dāng)前的是各個(gè)分支,每一個(gè)文件記錄了該分支最后一個(gè)提交結(jié)點(diǎn)的 sha-1 值疚宇。

    2. refs/tags 目錄下記錄的是各個(gè)標(biāo)簽亡鼠。

    3. refs/remotes 存儲(chǔ)當(dāng)前倉(cāng)庫(kù)配置的遠(yuǎn)程服務(wù)器。其每一個(gè)子目錄就對(duì)應(yīng)著一個(gè)遠(yuǎn)程倉(cāng)庫(kù) —— 子目錄名字就是通過(guò) git remote add <別名> url 中的別名敷待。子目錄下的各個(gè)文件指的是遠(yuǎn)程倉(cāng)庫(kù)的各個(gè)分支间涵。

  3. HEAD 文件指示目前被檢出的分支;

  4. index 文件保存暫存區(qū)信息榜揖。

  5. config 文件保存 --local 的配置信息勾哩。例如我們使用 git remote add <別名> url 命令時(shí),會(huì)在 config 文件中添加如下信息举哟。其具體信息可參考 remote一節(jié):

    [remote "demo"]
        url = https://github.com/birdandcliff/gitdemo.git
        fetch = +refs/heads/re:refs/remotes/demo/devlocal
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末思劳,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子炎滞,更是在濱河造成了極大的恐慌敢艰,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件册赛,死亡現(xiàn)場(chǎng)離奇詭異钠导,居然都是意外死亡震嫉,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門牡属,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)票堵,“玉大人,你說(shuō)我怎么就攤上這事逮栅°彩疲” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵措伐,是天一觀的道長(zhǎng)特纤。 經(jīng)常有香客問(wèn)我,道長(zhǎng)侥加,這世上最難降的妖魔是什么捧存? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮担败,結(jié)果婚禮上昔穴,老公的妹妹穿的比我還像新娘。我一直安慰自己提前,他們只是感情好吗货,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著狈网,像睡著了一般宙搬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上孙援,一...
    開(kāi)封第一講書(shū)人閱讀 51,688評(píng)論 1 305
  • 那天害淤,我揣著相機(jī)與錄音扇雕,去河邊找鬼拓售。 笑死,一個(gè)胖子當(dāng)著我的面吹牛镶奉,可吹牛的內(nèi)容都是我干的础淤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼哨苛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鸽凶!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起建峭,我...
    開(kāi)封第一講書(shū)人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤玻侥,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后亿蒸,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體凑兰,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡掌桩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了姑食。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片波岛。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖音半,靈堂內(nèi)的尸體忽然破棺而出则拷,到底是詐尸還是另有隱情,我是刑警寧澤曹鸠,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布煌茬,位于F島的核電站,受9級(jí)特大地震影響彻桃,放射性物質(zhì)發(fā)生泄漏宣旱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一叛薯、第九天 我趴在偏房一處隱蔽的房頂上張望浑吟。 院中可真熱鬧,春花似錦耗溜、人聲如沸组力。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)燎字。三九已至,卻和暖如春阿宅,著一層夾襖步出監(jiān)牢的瞬間候衍,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工洒放, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蛉鹿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓往湿,卻偏偏與公主長(zhǎng)得像妖异,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子领追,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Git 基礎(chǔ) 基本原理 客戶端并不是只提取最新版本的文件快照他膳,而是把代碼倉(cāng)庫(kù)完整的鏡像下來(lái)。這樣一來(lái)绒窑,任何一處協(xié)同...
    __silhouette閱讀 15,887評(píng)論 5 147
  • 以下筆記主要參考gitgot棕孙,大致了解git使用和原理。 第一部分我們從個(gè)人的視角去研究如何用好Git,并且揭示G...
    carolwhite閱讀 2,383評(píng)論 0 1
  • 這本書(shū)已經(jīng)讀完了一段時(shí)間蟀俊,可是遲遲不敢動(dòng)筆寫分歇,怕自己寫不出文里的精髓。 再次打開(kāi)這本書(shū)是在去西安的高鐵上欧漱,也許正好...
    白水若千閱讀 153評(píng)論 0 1
  • 成都真是一座溫柔的城市职抡。只在夜里下雨。沒(méi)有那么多赤裸裸的晴朗误甚,仿佛就是不想叫你參透人生缚甩,然后在你最絕望的時(shí)候,來(lái)一...
    迷鹿少女LuC閱讀 1,586評(píng)論 1 8
  • 一:web.xml加載過(guò)程簡(jiǎn)單說(shuō)一下窑邦,web.xml的加載過(guò)程擅威。當(dāng)我們啟動(dòng)一個(gè)WEB項(xiàng)目容器時(shí),容器包括(JBos...
    把愛(ài)放下會(huì)走更遠(yuǎn)閱讀 3,648評(píng)論 0 6