Git 底層原理

2021-09-22 21:08:33 字數 3699 閱讀 8205

二. .git 目錄結構

三.git add 與 git commit 簡單原理

四.建立與合併分支簡單原理

五.git rebase 簡單原理

六.開始從底層入手 git

七.git add 命令底層原理

八.git add 和 git commit 中間的操作(tree 物件的生成)

九.git commit 命令底層原理

git 常用命令

git 常見場景操作

git 底層原理的講解中看到一篇非常非常贊的博文,此文中有很多內容摘自下面這篇博文,做了小彙總,強烈推薦

yelbosh 大神的 git 博文

目前最先進的開源分布式版本控制系統,**思想是,**開發了多個版本,以往的思想是每個版本在電腦中 copy 乙份儲存,以免以後版本的**出現問題,可以直接找之前幾個版本的**,這種就好似只有兩層多子樹的樹形結構,git 的思想是自己電腦中不用 copy 下來每個版本,每個版本邏輯上是乙個結點,每次更新到下乙個版本,結點就自動往後延伸,是乙個線性結構,若想恢復到之前哪個版本,也就是恢復到之前哪個結點,可以用 git 相關命令來將版本變為歷史版本。git 比其他版本控制優秀在於其跟蹤管理是改動而不是檔案本身

1991 年 linus 建立了開源的 linux,自此 linux 不斷發展成為伺服器系統首選,2002 年之前各地開源 linux 的**貢獻者通過 diff 方式把源**發給 linus,然後 linus 本人通過手工方式合併**,linus 那時堅定反對 csv 和 svn,因為這些集中式版本控制系統不但速度慢而且需要聯網才行,雖然有一些好用的商用版本控制系統,可惜需要付費,這與 linus 提倡的開源精神不符合,到 2002 年 linux **庫已經大到 linus 很難維護了,社群成員也對此表示不滿,於是 linus 選擇使用了商業版本控制系統 bitkeeper,該系統的公司處於人道主義授權 linux 社群免費使用該版本控制系統,可是在 2005 年的時候,liunx 社群中的開發 samba 的安德魯檢視破解 bitkeeper 協議,其實還有社群裡的其他人,被 bitkeeper 公司發現,一氣之下,公司決定收回 linux 社群免費授權,之後 linus 沒有選擇向 bitkeeper 所有的公司道歉,而是選擇自己花了兩周左右的時間自己用 c 寫了乙個分布式版本控制系統,這就是 git,乙個月的之內 linux 系統原始碼已經可以被 git 管理了,接著 git 就迅速成為最流行的分布式版本控制系統,2008 年的時候,github 上線,無數開源專案通過 git 儲存在 github 中直到現今

git 工作區有個隱藏目錄 .git,這是 git 的版本庫,其中有暫存區,預設的 master 分支以及指向 master 的 head 指標

進入隱藏的 .git 目錄之後可以看到如上圖所示結構

sha-1 演算法介紹說明:其實 sha-1 演算法在兩千零幾年中國已經被攻破,有人就提出 git 的安全性問題,由於 git 是 linus 在此演算法還沒被攻破時候建立,linus 現在不以為然,因為他認為沒有人會發這麼大經理偷偷篡改他人**樹,他認為即使是使用老掉牙的 md5 都是可行,未來 git 中的 sha-1 演算法還是有可能被替換,參見

其他檔案

我們可以看到 .git 目錄中的檔案會因為幾次提交就成倍的增長,因為其中要生成物件

平時我們在工作區修改檔案,沒有 add 操作之前我們通過 git status 命令可以檢視到有檔案被 modified 而且是 not staged,這個時候修改的檔案僅僅是在工作區內,之後通過 git add 操作,被修改的檔案從工作區提交到暫存區(驛站)也就是stage裡,再通過 commit 操作把暫存區 stage 中所有的內容全部提交到當前的分支結構當中,即

工作區(檔案修改後 add 前)→ stage 暫存區(add 後 commit 前)→ 本地分支結構(本地 commit 後)

這樣的一種三層結構

分支被合併可以被 -d 刪除,分支沒有被合併後 -d 刪除會出錯,需要 -d 強制刪除

把乙個分支的修改整合到另乙個分支的辦法有兩種,第一種就是 git merge 操作,另一種就是 git rebase 操作,該命令原理就是回到兩個分支最近的共同祖先,根據當前分支(也就是要進行衍合的分支experiment)後續的歷次提交物件(這裡只有乙個 c3),生成一系列檔案補丁,然後以基底分支(也就是主幹分支master)最後乙個提交物件(c4)為新的出發點,逐個應用之前準備好的補丁檔案,最後會生成乙個新的合併提交物件(c3』),從而改寫 experiment 的提交歷史,使它成為 master 分支的直接下游。如下圖所示:

git 命令分為 procelain 和 plumbing 命令,前者是基於後者來實現的,若把 git 看成乙個作業系統那麼 plumbing 命令更像是乙個 shell 命令,而 procelain 命令就像是通過利用 shell 命令編寫的一系列系統功能或工具,下面會重點講解 plumbing 命令以及 git 物件

stage 暫存區又叫索引庫,因為暫存區資訊內容儲存在 .git 目錄結構的 index 資料夾,git add 就是把工作區 modified 檔案新增到 stage 暫存區,那麼 git add 底層是如何通過 plumbing 命令完成檔案索引操作的?

git 中所有內容以 blob 或者 tree 物件形式儲存。如果把 git 看做 unix 系統,那麼 tree 物件就好似檔案系統中的目錄,blob 物件就好似 inodes 或檔案內容。我們平時操作的 add 和 commit 操作似乎沒有涉及到這個 tree 物件的生成,其實有的,tree 物件只是 add 和 commit 中間的乙個緩衝步驟,因為 commit 物件要根據 tree 物件來建立,下面建立 tree 物件:

git write-tree #根據索引庫中的資訊建立tree物件
這條命令的作用是返回生成 tree 物件的 key 值

整個工作目錄對應乙個 tree 物件,並且其下每乙個子資料夾都是乙個 tree 物件,每次的 commit 物件都對應著根 tree 物件,任何乙個物件的改變都會導致其上層所有 tree 物件的重新儲存

index 暫存區包括了專案倉庫中所有的檔案,commit 物件所對應的 tree 物件永遠都是工作區根目錄所對應的 tree 物件,也就是說每次 commit 之後,commit 物件會依附在這個工作區的 tree 物件上。要是仔細觀察目錄結構的話,可以發現物件資料夾,子資料夾對應著乙個 tree 結點,檔案的話對應著乙個 blob 結點,建立 commit 物件的命令:

git commit-tree key –p key2 #根據tree物件建立commit物件,-p表示前繼commit物件
該命令實現的操作類似於資料結構樹中增加結點的操作,在這個命令中若是第一次提交則不需要指定 -p 選項指明父節點

git 常用命令

git 常見場景操作

GIT底層原理(一)

暫存操作會對先每乙個檔案計算校驗和checksum git 使用sha 1 演算法計算資料的校驗和,通過對檔案的內容或目錄的結構計算出乙個sha 1 雜湊值,作為指紋字串,該字串由40 個十六進製制字元,並將此結果作為資料的唯一標識和索引 然後把當前版本的檔案快照儲存到本地git 倉庫中 git 使...

git底層原理(二)

git物件模型 在git系統中有四種型別的物件,所有的git操作都是基於這四種型別的物件 blob 這種物件用來儲存檔案的內容。tree 可以理解成乙個物件關係樹,它管理一些 tree 和 blob 物件。commit 指向乙個 tree 它用來標記專案某乙個特定時間點的狀態。它包括以下關於時間點的...

Git底層原理和結構

基礎 一 資料結構 git object 1.blob物件 echo contents a.txt會在工作目錄建立a.txt,寫入contents。即在資料結構中建立blob物件節點。echo 222 git hash object w stdin會返回儲存在git庫中的唯一鍵。w 選項會指示該命令...