成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

這才是真正的Git——Git內部原理

開源
本文以一個具體例子結合動圖介紹了Git的內部原理,包括Git是什么儲存我們的代碼和變更歷史的、更改一個文件時,Git內部是怎么變化的、Git這樣實現的有什么好處等等。

 本文以一個具體例子結合動圖介紹了Git的內部原理,包括Git是什么儲存我們的代碼和變更歷史的、更改一個文件時,Git內部是怎么變化的、Git這樣實現的有什么好處等等。

[[317591]]

通過例子解釋清楚上面這張動圖,讓大家了解Git的內部原理。如果你已經能夠看懂這張圖了,下面的內容可能對你來說會比較基礎。

前言

近幾年技術發展十分迅猛,讓部分同學養成了一種學習知識停留在表面,只會調用一些指令的習慣。我們時常有一種“我會用這個技術、這個框架”的錯覺,等到真正遇到問題,才發現事情沒有那么簡單。

后來我開始沉下心,回歸一開始接觸編程的時候,那時候學習一個知識都會深入一點去思考背后的原理。但這并不是說掌握并會使用高級Api不重要,他們也非常重要,并且是日常工作中大部分時間都在使用的,快速掌握它們意味著高效學習,可以快速的應用在開發生產上。

只是有時候知道一些底層的東西,可以更好的幫你理清思路,知道你真正在操作什么,不會迷失在Git大量的指令和參數上面。

Git是怎么儲存信息的

這里會用一個簡單的例子讓大家直觀感受一下git是怎么儲存信息的。

首先我們先創建兩個文件

  1. $ git init 
  2. $ echo '111' > a.txt 
  3. $ echo '222' > b.txt 
  4. $ git add *.txt 

Git會將整個數據庫儲存在 .git/ 目錄下,如果你此時去查看 .git/objects 目錄,你會發現倉庫里面多了兩個object。

  1. $ tree .git/objects 
  2. .git/objects 
  3. ├── 58 
  4. │ └── c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c 
  5. ├── c2 
  6. │ └── 00906efd24ec5e783bee7f23b5d7c941b0c12c 
  7. ├── info 
  8. └── pack 

好奇的我們來看一下里面存的是什么東西

  1. $ cat .git/objects/58/c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c 
  2. xKOR0a044K% 

怎么是一串亂碼?這是因為Git將信息壓縮成二進制文件。但是不用擔心,因為Git也提供了一個能夠幫助你探索它的api git cat-file [-t] [-p] , -t 可以查看object的類型, -p 可以查看object儲存的具體內容。

  1. $ git cat-file -t 58c9 
  2. blob 
  3. $ git cat-file -p 58c9 
  4. 111 

可以發現這個object是一個blob類型的節點,他的內容是111,也就是說這個object儲存著a.txt文件的內容。

這里我們遇到第一種Git object,blob類型,它只儲存的是一個文件的內容,不包括文件名等其他信息。然后將這些信息經過SHA1哈希算法得到對應的哈希值 58c9bdf9d017fcd178dc8c073cbfcbb7ff240d6c,作為這個object在Git倉庫中的唯一身份證。

也就是說,我們此時的Git倉庫是這樣子的:

 

這才是真正的Git——Git內部原理

 

我們繼續探索,我們創建一個commit。

  1. $ git commit -am '[+] init' 
  2. $ tree .git/objects 
  3. .git/objects 
  4. ├── 0c 
  5. │ └── 96bfc59d0f02317d002ebbf8318f46c7e47ab2 
  6. ├── 4c 
  7. │ └── aaa1a9ae0b274fba9e3675f9ef071616e5b209 
  8. ... 

我們會發現當我們commit完成之后,Git倉庫里面多出來兩個object。同樣使用 cat-file 命令,我們看看它們分別是什么類型以及具體的內容是什么。

  1. $ git cat-file -t 4caaa1 
  2. tree 
  3. $ git cat-file -p 4caaa1 
  4. 100644 blob 58c9bdf9d017fcd178dc8c0...  a.txt 
  5. 100644 blob c200906efd24ec5e783bee7...  b.txt 

這里我們遇到了第二種Git object類型——tree,它將當前的目錄結構打了一個快照。從它儲存的內容來看可以發現它儲存了一個目錄結構(類似于文件夾),以及每一個文件(或者子文件夾)的權限、類型、對應的身份證(SHA1值)、以及文件名。

此時的Git倉庫是這樣的:

 

這才是真正的Git——Git內部原理
  1. $ git cat-file -t 0c96bf 
  2. commit 
  3. $ git cat-file -p 0c96bf 
  4. tree 4caaa1a9ae0b274fba9e3675f9ef071616e5b209 
  5. author lzane 李澤帆 1573302343 +0800 
  6. committer lzane 李澤帆 1573302343 +0800 
  7. [+] init 

接著我們發現了第三種Git object類型——commit,它儲存的是一個提交的信息,包括對應目錄結構的快照tree的哈希值,上一個提交的哈希值(這里由于是第一個提交,所以沒有父節點。在一個merge提交中還會出現多個父節點),提交的作者以及提交的具體時間,最后是該提交的信息。

此時我們去看Git倉庫是這樣的:

 

這才是真正的Git——Git內部原理

 

到這里我們就知道Git是怎么儲存一個提交的信息的了,那有同學就會問,我們平常接觸的分支信息儲存在哪里呢?

  1. $ cat .git/HEAD 
  2. ref: refs/heads/master 
  3.  
  4. $ cat .git/refs/heads/master 
  5. 0c96bfc59d0f02317d002ebbf8318f46c7e47ab2 

在Git倉庫里面,HEAD、分支、普通的Tag可以簡單的理解成是一個指針,指向對應commit的SHA1值。

 

這才是真正的Git——Git內部原理

 

其實還有第四種Git object,類型是tag,在添加含附注的tag( git tag -a )的時候會新建,這里不詳細介紹,有興趣的朋友按照上文中的方法可以深入探究。

至此我們知道了Git是什么儲存一個文件的內容、目錄結構、commit信息和分支的。 其本質上是一個key-value的數據庫加上默克爾樹形成的有向無環圖(DAG) 。這里可以蹭一下區塊鏈的熱度,區塊鏈的數據結構也使用了默克爾樹。

Git的三個分區

接下來我們來看一下Git的三個分區(工作目錄、Index 索引區域、Git倉庫),以及Git變更記錄是怎么形成的。了解這三個分區和Git鏈的內部原理之后可以對Git的眾多指令有一個“可視化”的理解,不會再經常搞混。

接著上面的例子,目前的倉庫狀態如下:

 

這才是真正的Git——Git內部原理

 

這里有三個區域,他們所儲存的信息分別是:

工作目錄 ( working directory ):操作系統上的文件,所有代碼開發編輯都在這上面完成。

索引( index or staging area ):可以理解為一個暫存區域,這里面的代碼會在下一次commit被提交到Git倉庫。

Git倉庫( git repository ):由Git object記錄著每一次提交的快照,以及鏈式結構記錄的提交變更歷史。

我們來看一下更新一個文件的內容這個過程會發生什么事。

 

這才是真正的Git——Git內部原理

 

運行 echo "333" > a.txt 將a.txt的內容從111修改成333,此時如上圖可以看到,此時索引區域和git倉庫沒有任何變化。

 

這才是真正的Git——Git內部原理

 

運行 git add a.txt 將a.txt加入到索引區域,此時如上圖所示,git在倉庫里面新建了一個blob object,儲存了新的文件內容。并且更新了索引將a.txt指向了新建的blob object。

 

這才是真正的Git——Git內部原理

 

運行 git commit -m 'update' 提交這次修改。如上圖所示

  • Git首先根據當前的索引生產一個tree object,充當新提交的一個快照。
  • 創建一個新的commit object,將這次commit的信息儲存起來,并且parent指向上一個commit,組成一條鏈記錄變更歷史。
  • 將master分支的指針移到新的commit結點。

至此我們知道了Git的三個分區分別是什么以及他們的作用,以及歷史鏈是怎么被建立起來的。**基本上Git的大部分指令就是在操作這三個分區以及這條鏈。 可以嘗試的思考一下git的各種命令,試一下你能不能夠在上圖將它們 “可視化”**出來,這個很重要,建議嘗試一下。

如果不能很好的將日常使用的指令“可視化”出來,推薦閱讀 圖解Git

一些有趣的問題

有興趣的同學可以繼續閱讀,這部分不是文章的主要內容

問題1:為什么要把文件的權限和文件名儲存在tree object里面而不是blob object呢?

想象一下修改一個文件的命名。

如果將文件名保存在blob里面,那么Git只能多復制一份原始內容形成一個新的blob object。而Git的實現方法只需要創建一個新的tree object將對應的文件名更改成新的即可,原本的blob object可以復用,節約了空間。

問題2:每次commit,Git儲存的是全新的文件快照還是儲存文件的變更部分?

由上面的例子我們可以看到,Git儲存的是全新的文件快照,而不是文件的變更記錄。也就是說,就算你只是在文件中添加一行,Git也會新建一個全新的blob object。那這樣子是不是很浪費空間呢?

這其實是Git在空間和時間上的一個取舍,思考一下你要checkout一個commit,或對比兩個commit之間的差異。如果Git儲存的是問卷的變更部分,那么為了拿到一個commit的內容,Git都只能從第一個commit開始,然后一直計算變更,直到目標commit,這會花費很長時間。而相反,Git采用的儲存全新文件快照的方法能使這個操作變得很快,直接從快照里面拿取內容就行了。

當然,在涉及網絡傳輸或者Git倉庫真的體積很大的時候,Git會有垃圾回收機制gc,不僅會清除無用的object,還會把已有的相似object打包壓縮。

問題3:Git怎么保證歷史記錄不可篡改?

通過SHA1哈希算法和哈系樹來保證。假設你偷偷修改了歷史變更記錄上一個文件的內容,那么這個問卷的blob object的SHA1哈希值就變了,與之相關的tree object的SHA1也需要改變,commit的SHA1也要變,這個commit之后的所有commit SHA1值也要跟著改變。又由于Git是分布式系統,即所有人都有一份完整歷史的Git倉庫,所以所有人都能很輕松的發現存在問題。

希望大家讀完有所收獲,下一篇文章會寫一些我日常工作中覺得比較實用的Git技巧、經常被問到的問題、以及發生一些事故時的處理方法。

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2020-05-28 10:45:31

Git分支合并

2020-08-25 23:06:33

開發技能代碼

2024-08-07 10:24:04

2018-07-27 10:39:13

對象存儲Git

2016-12-16 19:06:02

擴展數據庫架構

2012-05-17 11:04:18

匈牙利命名法

2015-02-11 09:35:09

iPhone6

2015-08-17 13:19:55

大數據

2015-04-03 10:11:57

Windows 10免費

2021-01-19 05:44:53

危機面試技術

2025-04-02 02:12:00

用戶分析業務數據

2025-03-05 00:01:00

用戶分層平均數消費

2022-11-14 11:55:39

數據分析項目

2022-11-29 11:31:19

商品分析商品銷售庫存

2024-05-10 12:01:00

商品分析數據分析斷貨

2023-06-16 11:54:59

數據分析項目

2022-03-10 15:55:44

元宇宙VRVR辦公

2017-10-16 15:33:35

微信APP小程序

2021-12-15 07:24:56

SocketTCPUDP

2021-02-05 15:01:41

GitLinux命令
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一级av毛片 | 久久伊人影院 | 欧美一区二区三区在线播放 | 成人免费视频网站 | 成人精品久久日伦片大全免费 | 亚洲综合精品 | 国产精品一区二区三区久久 | a在线免费观看 | 久久视频精品 | 在线成人av | 秋霞国产 | 中文字幕欧美一区 | 久久国产精品一区二区三区 | av手机在线免费观看 | 成人亚洲在线 | 福利久久 | www.狠狠干 | av网站免费观看 | 91精品国产91久久久久久吃药 | 欧美又大粗又爽又黄大片视频 | 亚洲精品丝袜日韩 | 国产精品视频免费观看 | 超碰伊人久久 | 久久精彩视频 | 一区二区三区小视频 | 少妇久久久 | 国产一区二区三区在线 | 日韩视频在线观看一区二区 | 高清视频一区二区三区 | 91视频进入| 欧美精品一区二区免费 | 免费色网址 | 一二区成人影院电影网 | 久久久免费 | 91精品一区 | 免费一级黄色电影 | 日韩欧美中文字幕在线观看 | 91资源在线| 高清国产一区二区 | 久久精品国产99国产精品 | 日本在线视频一区二区 |