GIT原理 GIT如何管理你的代碼 commit tree blob

[toc]

引用

抄自 https://www.bilibili.com/video/BV11z4y1X79p?spm_id_from=333.337.search-card.all.click 該鏈接

并且結(jié)合 PRO_GIT 一書總結(jié)

git 不關(guān)注差異副硅,只關(guān)注當(dāng)前快照

git和svn的一大區(qū)別是弄诲,svn關(guān)注的是修改微猖,git關(guān)注當(dāng)前現(xiàn)狀盟猖。

比方說胆绊,一個空房間里有兩個箱子。每次這兩個箱子移動嗽交,svn都會記錄他們的移動路線篮幢,但是git不在乎,它只會在你commit的時候穷缤,拿著相機進屋拍個照敌蜂,箱子在哪就是哪里,愛咋咋地津肛。


image.png

Git 不按照以上方式對待或保存數(shù)據(jù)章喉。反之,Git 更像是把數(shù)據(jù)看作是對小型文件系統(tǒng)的一系列快照。 在 Git
中秸脱,每當(dāng)你提交更新或保存項目狀態(tài)時落包,它基本上就會對當(dāng)時的全部文件創(chuàng)建一個快照并保存這個快照的索引。為了效率摊唇,如果文件沒有修改咐蝇,Git 不再重新存儲該文件,而是只保留一個鏈接指向之前存儲的文件巷查。 Git 對待數(shù)據(jù)更像是一個 快照流有序。

image.png

git commit tree blob 結(jié)構(gòu)圖

現(xiàn)在,Git 倉庫中有五個對象:三個 blob 對象(保存著文件快照)吮便、一個 樹 對象 (記錄著目錄結(jié)構(gòu)和 blob 對象索引)以及一個 提交 對象(包含著指向前述樹對象的指針和所有提交信息)笔呀。


image.png

做些修改后再次提交,那么這次產(chǎn)生的提交對象會包含一個指向上次提交對象(父對象)的指針髓需。


image.png

./git 中的對象 commit tree blob

blob自行百度许师,總之這里你理解成個存儲數(shù)據(jù)的格式就行了

仿照視頻里面的步驟,我們也用個窗口僚匆,來觀察當(dāng)你執(zhí)行 add commit操作的時候微渠, ./git 里面發(fā)生了什么。同樣我們也刪除 hooks

git init后

.git
├── branches
├── config
├── description
├── HEAD
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags

8 directories, 4 files

變換一:新建test1.c咧擂, 之后add --生成blob

vi test1.c
寫一行 The Master Chief逞盆,然后 wq
這個時候沒有任何變化

git add test1.c
我們發(fā)現(xiàn)多了下面的object

.git
├── branches
├── config
├── description
├── HEAD
├── index
├── info
│   └── exclude
├── objects
│   ├── c2
│   │   └── 673408f719c6224ae85b27c9d4245ad96e55d6
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags

9 directories, 6 files

git cat-file -t c267
發(fā)現(xiàn)是 blob 類型

git cat-file -p c267
會顯示 The Master Chief

變化二:第一次 commit --生成tree和commit

git commit -m "first commit"
該操作會生成兩個新的 objects 作為 tree 和 commit

.git 
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           └── master
├── objects
│   ├── 12
│   │   └── 6dbd7bfa165928164e2807e0e6a42b4d85ac37
│   ├── 55
│   │   └── d9df99408ea612721fbe8ba7e18be1b7a3c594
│   ├── c2
│   │   └── 673408f719c6224ae85b27c9d4245ad96e55d6
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags

14 directories, 12 files

這里我們分別的 git cat-file -t git cat-file -p 看下

git cat-file -t 126d
顯示 commit

git cat-file -p 126d
顯示四行,分別是 tree/author/committer 和 和最后的commit信息

git cat-file -t 55d9
顯示 tree

git cat-file -p 55d9
顯示 100644 blob c2673408f719c6224ae85b27c9d4245ad96e55d6 test1.c
這里面的blob 剛好就是我們之前 add 的blob 對應(yīng)的文件

完全相同的文件松申,將會使用同一個blob

創(chuàng)建一個test2.c云芦,內(nèi)容完全和 test1.c 一致,觀察

vi test2.c
寫一行 The Master Chief贸桶,然后 wq
這個時候沒有任何變化

git add test2.c
結(jié)果.git文件夾里面的內(nèi)容毫無變化

.git 
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           └── master
├── objects
│   ├── 12
│   │   └── 6dbd7bfa165928164e2807e0e6a42b4d85ac37
│   ├── 55
│   │   └── d9df99408ea612721fbe8ba7e18be1b7a3c594
│   ├── c2
│   │   └── 673408f719c6224ae85b27c9d4245ad96e55d6
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags

14 directories, 12 files

第二次commit

git commit -m "second commit"
該操作會再生成兩個新的 objects 作為 tree 和 commit

.git 
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           └── master
├── objects
│   ├── 12
│   │   └── 6dbd7bfa165928164e2807e0e6a42b4d85ac37
│   ├── 55
│   │   └── d9df99408ea612721fbe8ba7e18be1b7a3c594
│   ├── 8f
│   │   └── ddf9dedce34df33de41c544e7bf6213494e9e4
│   ├── b9
│   │   └── be6a158220da6aa0cd39e64402d7909a217773
│   ├── c2
│   │   └── 673408f719c6224ae85b27c9d4245ad96e55d6
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags

16 directories, 14 files

這里我們分別的 git cat-file -t git cat-file -p 看下

git cat-file -t 8fdd
顯示 commit

git cat-file -p 8fdd
顯示五行舅逸,分別是 tree/parent/author/committer 和 和 second commit

git cat-file -t b9be
顯示 tree

git cat-file -p b9be
顯示

100644 blob c2673408f719c6224ae85b27c9d4245ad96e55d6    test1.c
100644 blob c2673408f719c6224ae85b27c9d4245ad96e55d6    test2.c

可以看到tree里面引用了 一模一樣的blob

修改同一個文件,將生成額外的blob

修改 test1.c皇筛,然后add

現(xiàn)在我們修改 vi test1.c琉历,另起一行加入一句 Spartan 117,然后 wq

git add test1.c
多了一條object ``38a1```

.git 
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           └── master
├── objects
│   ├── 12
│   │   └── 6dbd7bfa165928164e2807e0e6a42b4d85ac37
│   ├── 38
│   │   └── a13225d42cba196f7f183ce0b17e0ec31b7cd9
│   ├── 55
│   │   └── d9df99408ea612721fbe8ba7e18be1b7a3c594
│   ├── 8f
│   │   └── ddf9dedce34df33de41c544e7bf6213494e9e4
│   ├── b9
│   │   └── be6a158220da6aa0cd39e64402d7909a217773
│   ├── c2
│   │   └── 673408f719c6224ae85b27c9d4245ad96e55d6
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags

17 directories, 15 files

檢查一下這個 38a1

git cat-file -t 38a1
顯示 blob

git cat-file -p 38a1
顯示

The Master Chief
Spartan 117

第三次 commit水醋,生成新的 tree 和 commit

git commit -m "third commit"
該操作會再生成兩個新的 objects 作為 tree 和 commit

4d65 5385

.git 
├── branches
├── COMMIT_EDITMSG
├── config
├── description
├── HEAD
├── index
├── info
│   └── exclude
├── logs
│   ├── HEAD
│   └── refs
│       └── heads
│           └── master
├── objects
│   ├── 12
│   │   └── 6dbd7bfa165928164e2807e0e6a42b4d85ac37
│   ├── 38
│   │   └── a13225d42cba196f7f183ce0b17e0ec31b7cd9
│   ├── 4d
│   │   └── 65a099692964508d4cab2dc6f4764e2e8bfeae
│   ├── 53
│   │   └── 854de4bae0ad5aaeb7f841da470fbec0008a78
│   ├── 55
│   │   └── d9df99408ea612721fbe8ba7e18be1b7a3c594
│   ├── 8f
│   │   └── ddf9dedce34df33de41c544e7bf6213494e9e4
│   ├── b9
│   │   └── be6a158220da6aa0cd39e64402d7909a217773
│   ├── c2
│   │   └── 673408f719c6224ae85b27c9d4245ad96e55d6
│   ├── info
│   └── pack
└── refs
    ├── heads
    │   └── master
    └── tags

19 directories, 17 files

git cat-file -t 4d65
顯示 commit

git cat-file -p 4d65
顯示五行旗笔,分別是 tree/parent/author/committer 和 third commit

git cat-file -t 5385
顯示 tree

git cat-file -p 5385
顯示

100644 blob 38a13225d42cba196f7f183ce0b17e0ec31b7cd9    test1.c
100644 blob c2673408f719c6224ae85b27c9d4245ad96e55d6    test2.c

當(dāng)前的tree引用了 test1.c的新blob 38a1,但是原先的 test1.c blob并沒有消失拄踪,依然保存在 ./git

這也就是為什么 git reset 的時候你能很快的回到當(dāng)前commit點蝇恶,因為直接通過指針,找到了對應(yīng)的tree和blob

test1.c 又改回到第一次commit的狀態(tài)惶桐,新commit一次艘包,tree會怎么變

tree會回到第一次的狀態(tài)的猛,雖然他們上面的commit點哈希值不一樣,tree本身的哈希值也不一樣想虎,但是tree的內(nèi)容會一樣

reset --hard 對 .git 內(nèi) objects 的影響

事實上是沒有影響卦尊,所有已經(jīng)存在的 objects 都會被保留。所以reset --hard 并不是不能恢復(fù)的舌厨,但是如果你刪除掉本地的庫岂却,又沒有遠程庫保存,那么就徹底不能恢復(fù)了裙椭,因為你的 objects 都被干掉了

剛才有三次commit躏哩,我reset --hard 到第一次,再cherry之前的commit點哈希揉燃,發(fā)現(xiàn)是可以cherry-pick的扫尺。

所以,如果不小心 reset --hard炊汤,遠端也沒有保存正驻,
千萬不要隨便刪除本地庫的文件夾,沒有這個.git你就徹底恢復(fù)不了了

git分支原理 && 為什么 git 分支切換速度快

svn如果你創(chuàng)建一個分支抢腐,它會將自己的所有的代碼全部復(fù)制一份姑曙,然后建立一個新分支。

git的分支不同迈倍,它只是一個指針伤靠,指向了你的某個commit點,相當(dāng)于你創(chuàng)建一個新分支的時候啼染,只不過是創(chuàng)建了一個指針而已宴合。

之前提過,或者結(jié)合下圖迹鹅,我們打印commit點的時候卦洽,會生成5行內(nèi)容
分別是 tree/parent/author/committer

其中parent就是指向父commit點的指針

image.png

首次提交產(chǎn)生的提交對象沒有父對象徒欣,普通提交操
作產(chǎn)生的提交對象有一個父對象逐样, 而由多個分支合并產(chǎn)生的提交對象有多個父對象
蜗字。

git在管理代碼時打肝,如果出現(xiàn)reset rebase pull merge等等改變當(dāng)前commit點的操作時,會根據(jù)最終的commit點指針挪捕,找到它下面連著的tree粗梭,再找到tree對應(yīng)的blob文件,瞬間恢復(fù)到該commit點應(yīng)該有的狀態(tài)级零。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末断医,一起剝皮案震驚了整個濱河市滞乙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌鉴嗤,老刑警劉巖斩启,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異醉锅,居然都是意外死亡兔簇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門硬耍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來垄琐,“玉大人,你說我怎么就攤上這事经柴±昃剑” “怎么了?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵坯认,是天一觀的道長翻擒。 經(jīng)常有香客問我,道長鹃操,這世上最難降的妖魔是什么韭寸? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮荆隘,結(jié)果婚禮上恩伺,老公的妹妹穿的比我還像新娘。我一直安慰自己椰拒,他們只是感情好晶渠,可當(dāng)我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著燃观,像睡著了一般褒脯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缆毁,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天番川,我揣著相機與錄音,去河邊找鬼脊框。 笑死颁督,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的浇雹。 我是一名探鬼主播沉御,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼昭灵!你這毒婦竟也來了吠裆?” 一聲冷哼從身側(cè)響起伐谈,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎试疙,沒想到半個月后诵棵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡祝旷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年非春,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片缓屠。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡奇昙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出敌完,到底是詐尸還是另有隱情储耐,我是刑警寧澤,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布滨溉,位于F島的核電站什湘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏晦攒。R本人自食惡果不足惜闽撤,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望脯颜。 院中可真熱鬧哟旗,春花似錦、人聲如沸栋操。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矾芙。三九已至舍沙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間剔宪,已是汗流浹背拂铡。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留葱绒,地道東北人感帅。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像哈街,于是被迫代替她去往敵國和親留瞳。 傳聞我的和親對象是個殘疾皇子拒迅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,901評論 2 355

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