91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Git的原理是什么

發布時間:2021-07-10 14:12:15 來源:億速云 閱讀:158 作者:chen 欄目:大數據

這篇文章主要介紹“Git的原理是什么”,在日常操作中,相信很多人在Git的原理是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Git的原理是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

說起Git,相信大家都很熟悉了,畢竟作為程序猿,每天的業余時間除了吃飯睡覺就是逛一下全世界最大的開(tong)源(xing)代(jiao)碼(you)網站GitHub了。在那里Git是每個人所要具備的最基本的技能。今天我們不聊Git的基本應用,來聊一聊Git的原理。<!-- more -->

Git給自己的定義是一套內存尋址文件系統,當你在一個目錄下執行git init命令時,會生成一個.git目錄,它的目錄結構是這樣的:

.git/
├── branches
├── config
├── description
├── HEAD
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── prepare-commit-msg.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
   ├── heads
   └── tags

其中branches目錄已經不再使用,description文件僅供GitWeb程序使用,config文件保存了項目的配置。

需要我們重點關注的是HEAD和index文件以及objects和refs目錄。其中index中保存了暫存區的一些信息,這里不做過多介紹。

objects目錄

這個目錄是用來存儲Git對象的(包括tree對象、commit對象和blob對象),對于一個初始的Git倉庫,objects目錄下只有info和pack兩個子目錄,并沒有常規文件。隨著項目的進行,我們創建的文件,以及一些操作記錄,都會作為Git對象被存儲在這個目錄下。

在該目錄下,所有對象都會生成一個文件,并且有對應的SHA-1校驗和,Git會創建以校驗和前兩位為名稱的子目錄,并以剩下的38位為名稱來保存文件。

接下來讓我們一起看一下當我們進行一次提交時,Git具體做了哪些事情。

$ echo 'test content'>test.txt
$ git add .

執行上述命令后,objects目錄結構如下:

.git/objects/
├── d6
│   └── 70460b4b4aece5915caf5c68d12f560a9fe3e4
├── info
└── pack

這里多了一個文件夾,如上面所述,這個就是Git為我們創建的一個對象,我們可以使用底層命令來看一下這個對象的類型以及它存儲的是什么。

$ git cat-file -t d670460b4b4aece5915caf5c68d12f560a9fe3e4
blob
$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
test content

可以看到,這是一個blob對象,存儲內容就是我們剛剛創建的文件的內容。接下來繼續執行提交操作。

$ git commit -m 'test message'
[master (root-commit) 2b00dca] test message
1 file changed, 1 insertion(+)
create mode 100644 test.txt
$ tree .git/objects/
.git/objects/
├── 2b
│   └── 00dcae50af70bb5722033b3fe75281206c74da
├── 80
│   └── 865964295ae2f11d27383e5f9c0b58a8ef21da
├── d6
│   └── 70460b4b4aece5915caf5c68d12f560a9fe3e4
├── info
└── pack

此時objects目錄下又多了兩個對象。再用cat-file命令來查看一下這兩個文件。

$ git cat-file -t 2b00dcae50af70bb5722033b3fe75281206c74da
commit
$ git cat-file -p 2b00dcae50af70bb5722033b3fe75281206c74da
tree 80865964295ae2f11d27383e5f9c0b58a8ef21da
author jackeyzhe <jackeyzhe59@163.com> 1534670725 +0800
committer jackeyzhe <jackeyzhe59@163.com> 1534670725 +0800

test message
$ git cat-file -t 80865964295ae2f11d27383e5f9c0b58a8ef21da
tree
$ git cat-file -p 80865964295ae2f11d27383e5f9c0b58a8ef21da
100644 blob d670460b4b4aece5915caf5c68d12f560a9fe3e4    test.txt

可以看到一個是commit對象,一個是tree對象。commit對象通常包括4部分內容:

  • 工作目錄快照的Hash,即tree的值

  • 提交的說明信息

  • 提交者的信息

  • 父提交的Hash值

由于我是第一次提交,所以這里沒有父提交的Hash值。

tree對象可以理解為UNIX文件系統中的目錄,保存了工作目錄的tree對象和blob對象的信息。接下來我們再來看一下Git是如何進行版本控制的。

echo 'version1'>version.txt
$ git add .
$ git commit -m 'first version'
[master 702193d] first version
1 file changed, 1 insertion(+)
create mode 100644 version.txt
$ echo 'version2'>version.txt
$ git add .
$ git commit -m 'second version'
[master 5333a75] second version
1 file changed, 1 insertion(+), 1 deletion(-)
$ tree .git/objects/
.git/objects/
├── 1f
│   └── a5aab2a3cf025d06479b9eab9a7f66f60dbfc1
├── 29
│   └── 13bfa5cf9fb6f893bec60ac11d86129d56fcbe
├── 2b
│   └── 00dcae50af70bb5722033b3fe75281206c74da
├── 53
│   └── 33a759c4bdcdc6095b4caac19743d9445ca516
├── 5b
│   └── dcfc19f119febc749eef9a9551bc335cb965e2
├── 70
│   └── 2193d62ffd797155e4e21eede20897890da12a
├── 80
│   └── 865964295ae2f11d27383e5f9c0b58a8ef21da
├── d6
│   └── 70460b4b4aece5915caf5c68d12f560a9fe3e4
├── df
│   └── 7af2c382e49245443687973ceb711b2b74cb4a
├── info
└── pack
$ git cat-file -p 1fa5aab2a3cf025d06479b9eab9a7f66f60dbfc1
100644 blob d670460b4b4aece5915caf5c68d12f560a9fe3e4    test.txt
100644 blob 5bdcfc19f119febc749eef9a9551bc335cb965e2    version.txt
$ git cat-file -p 2913bfa5cf9fb6f893bec60ac11d86129d56fcbe
100644 blob d670460b4b4aece5915caf5c68d12f560a9fe3e4    test.txt
100644 blob df7af2c382e49245443687973ceb711b2b74cb4a    version.txt

Git將沒有改變的文件的Hash值直接存入tree對象,對于有修改的文件,則會生成一個新的對象,將新的對象存入tree對象。我們再來看一下commit對象的信息。

$ git cat-file -p 5333a759c4bdcdc6095b4caac19743d9445ca516
tree 2913bfa5cf9fb6f893bec60ac11d86129d56fcbe
parent 702193d62ffd797155e4e21eede20897890da12a
author jackeyzhe <jackeyzhe59@163.com> 1534672270 +0800
committer jackeyzhe <jackeyzhe59@163.com> 1534672270 +0800

second version
$ git cat-file -p 702193d62ffd797155e4e21eede20897890da12a
tree 1fa5aab2a3cf025d06479b9eab9a7f66f60dbfc1
parent 2b00dcae50af70bb5722033b3fe75281206c74da
author jackeyzhe <jackeyzhe59@163.com> 1534672248 +0800
committer jackeyzhe <jackeyzhe59@163.com> 1534672248 +0800

first version

此時的commit對象已經有parent信息了,這樣我們就可以順著parent一步步往回進行版本回退了。不過這樣是比較麻煩的,我們一般習慣用的是git log查看提交記錄。

refs目錄

在介紹refs目錄之前,我們還是先來看一下該目錄結構

$ tree .git/refs/
.git/refs/
├── heads
│   └── master
└── tags

2 directories, 1 file
$ cat .git/refs/heads/master
5333a759c4bdcdc6095b4caac19743d9445ca516

在一個剛剛被初始化的Git倉庫中,refs目錄下只有heads和tags兩個子目錄,由于我們剛剛有過提交操作,所以git為我們自動生成了一個名為master的引用。master的內容是最后一次提交對象的Hash值。看到這里大家一定在想,如果我們對每次提交都創建一個這樣的引用,不就不需要記住每次提交的Hash值了,只要看看引用的值,復制過來就可以退回到對應版本了。沒錯,這樣是可以方便的退回,但是這樣做的意義不大,因為我們并不需要頻繁的退回,特別是比較古老的版本,退回的概率更是趨近于0。Git用這個引用做了更有意義的事,那就是分支。

當我新建一個分支時,git就會在.git/refs/heads目錄下新建一個文件。當然新建的引用還是指向當前工作目錄的最后一次提交,一般情況下我們不會主動去修改這些引用文件,不過如果一定要修改,Git為我們提供了一個update-ref命令。可以改變引用的值,使其指向不同的commit對象。

tags目錄下的文件存儲的是標簽對應的commit,當為某次提交打上一個tag時,tags目錄下就會被創建出一個命名為tag名的文件,值是此次提交的Hash值。

HEAD

新建分支的時候,Git是怎么知道我們當前是在哪個分支的,Git又是如何實現分支切換的呢?答案就在HEAD這個文件中。

$ cat .git/HEAD 
ref: refs/heads/master
$ git checkout test
Switched to branch 'test'
$ cat .git/HEAD
ref: refs/heads/test

很明顯,HEAD文件存儲的就是我們當前分支的引用,當我們切換分支后再次進行提交操作時,Git就會讀取HEAD對應引用的值,作為此次commit的parent。我們也可以通過symbolic-ref命令手動設置HEAD的值,但是不能設置refs以外的形式。

Packfiles

到這里我們在文章開頭所說的重點關注的目錄和文件都介紹完畢了。但是作為一個文件系統,還存在一個問題,那就是空間。前文介紹過,當文件修改后進行提交時,Git會創建一份新的快照。這樣長久下去,必定會占用很大的存儲空間。而比較古老的版本的價值已經不大,所以要想辦法清理出足夠的空間供用戶使用。

好消息是,Git擁有自己的gc(垃圾回收)方法。當倉庫中有太多松散對象時,Git會調用git gc命令(當然我們也可以手動調用這個命令),將這些對象進行打包。打包后會出現兩個新文件:一個idx索引文件和一個pack文件。索引文件包含了packfile的偏移信息,可以快速定位到文件。打包后,每個文件最新的版本的對象存的是完整的文件內容。而之前的版本只保存差異。這樣就達到了壓縮空間的目的。

到此,關于“Git的原理是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

git
AI

突泉县| 昌都县| 炎陵县| 平顶山市| 合水县| 湖南省| 永嘉县| 深州市| 雷山县| 集贤县| 礼泉县| 金门县| 射洪县| 阜城县| 云霄县| 华安县| 天柱县| 石阡县| 南皮县| 通州区| 通榆县| 许昌县| 会同县| 修文县| 荔浦县| 湖南省| 光泽县| 香港| 久治县| 南投市| 阳西县| 盘锦市| 成安县| 福泉市| 巴东县| 梁山县| 图木舒克市| 鲁山县| 澎湖县| 遂宁市| 八宿县|