0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

探究Git基本原理(下)

jf_78858299 ? 來源:分布式實(shí)驗(yàn)室 ? 作者:分布式實(shí)驗(yàn)室 ? 2023-05-12 15:20 ? 次閱讀

加深理解 commit 提交

執(zhí)行完成了 git commit 命令,究竟做了什么呢?

當(dāng)我們?cè)俅螌?duì) file2.txt 文件的內(nèi)容進(jìn)行變更、添加以及提交之后,發(fā)現(xiàn)在提交的時(shí)候,查看的 commit 對(duì)象的內(nèi)容時(shí),其包含有父節(jié)點(diǎn)的 commit 信息。而對(duì)于理解的話,可以看看下面的這個(gè)提交流程圖。

# 左邊執(zhí)行
$ echo "file2.txt" > file2.txt
$ git status
$ git add file2.txt
$ git ls-files -s
$ git cat-file -p 0ac9638
$ git commit -m "2nd commit"
$ git cat-file -p bab53ff
$ git cat-file -p 2f07720

# 右邊執(zhí)行
$ watch -n 1 -d tree .git

圖片

圖片

在 Git 中空文件夾是不算在追蹤范圍內(nèi)的,而且添加文件夾并不會(huì)增加 object 對(duì)象。當(dāng)我們查看 index 內(nèi)容的時(shí)候,會(huì)發(fā)現(xiàn)文件名稱是包含相對(duì)路徑的。

而當(dāng)我們通過 commit 命令提交之后,會(huì)發(fā)現(xiàn)生成了三個(gè) object 對(duì)象,因?yàn)?commit 操作不會(huì)生成 blob 對(duì)象,所以分別是一個(gè) commit 對(duì)象和兩個(gè) tree 對(duì)象。可以發(fā)現(xiàn),tree 對(duì)象里面有包含了一個(gè)目錄的 tree,其里面包含對(duì)象文件內(nèi)容。

下圖所示的文件狀態(tài),可以體會(huì)到 Git 中版本的概念。即 commit 對(duì)象指向一個(gè)該版本中的文件目錄樹的根(tree),然后 tree 在指向 blob 對(duì)象(文件)和 tree 對(duì)象(目錄),這樣就可以無限的往復(fù)下去形成一個(gè)完整的版本。

# 左邊執(zhí)行
$ mkdir floder1
$ echo "file3" > floder1/file3.txt
$ git add floder1
$ git ls-files -s
$ git commit -m "3rd commit"
$ git cat-file -p 1711e01
$ git cat-file -p 9ab67f8

# 右邊執(zhí)行
$ watch -n 1 -d tree .git

圖片

文件的生命周期狀態(tài)

總結(jié)一下,Git 里面的文件狀態(tài)和如何切換。

現(xiàn)在,我們已經(jīng)基本理解了文件如何在工作區(qū)、暫存區(qū)以及代碼倉庫之間進(jìn)行狀態(tài)的跟蹤和同步。在 Git 的操作中,文件的可能狀態(tài)有哪些,以及如何進(jìn)行狀態(tài)切換的,我們這里一起總結(jié)一下!

圖片

圖片

Branch 和 HEAD 的意義

執(zhí)行完成了 git branch 命令,究竟做了什么呢?

到底什么是分支?分支切換又是怎么一回事?我們通過查看 Git 的官方文檔,就可以得到,分支就是一個(gè)有名字的(master/dev)指向 commit 對(duì)象的一個(gè)指針。

我們?cè)诔跏蓟瘋}庫的時(shí)候,提供會(huì)默認(rèn)給我們分配一個(gè)叫做 master 的分支(在最新的版本默認(rèn)倉庫已經(jīng)變更為 main 了),而 master 分支就是指向最新的一次提交。為什么需要給分支起名字呢?就是為了方便我們使用和記憶,可以簡(jiǎn)單理解為 alias 命令的意義一致。

圖片

有了上述基礎(chǔ),我們就需要考慮下,分支到底是如何實(shí)現(xiàn)和工作的。要實(shí)現(xiàn)一個(gè)分支,我們最基本需要解決兩個(gè)問題,第一個(gè)就是需要存儲(chǔ)每一個(gè)分支指向的 commit,第二個(gè)問題就是在切換分支的時(shí)候幫助我們標(biāo)識(shí)當(dāng)前分支。

在 Git 中,它有一個(gè)非常特殊的 HEAD 文件。而 HEAD 文件是一個(gè)指針,其有一個(gè)特性就是總會(huì)指向當(dāng)前分支的最新的一個(gè) commit 對(duì)象。而這個(gè) HEAD 文件正好,解決了我們上面提出的兩個(gè)問題。

當(dāng)我們從 master 切換分支到 dev 的時(shí)候,HEAD 文件也會(huì)隨即切換,即指向 dev 這個(gè)指針。設(shè)計(jì)就是這么美麗,不愧是鬼才,好腦袋。

圖片

# 左邊執(zhí)行
$ cat .git/HEAD
$ cat .git/refs/heads/master
$ git cat-file -t 1711e01

# 右邊執(zhí)行
$ glo = git log

圖片

分支操作的背后邏輯

執(zhí)行完成了 git branch 命令,究竟做了什么呢?

這里我們可以看到分支切換之后,HEAD 指向發(fā)生變動(dòng)了。

# 左邊執(zhí)行
$ git branch
$ git branch dev
$ ll .git/refs/heads
$ cat .git/refs/heads/master
$ cat .git/refs/heads/dev
$ cat .git/HEAD
$ git checkout dev
$ cat .git/HEAD

# 右邊執(zhí)行
$ glo = git log

圖片

這里需要注意的是,即使我們刪除了分支,但是該分支上一些特有的對(duì)象并不會(huì)被刪除的。這些對(duì)象其實(shí)就是我們俗稱的垃圾對(duì)象,還有我們多次使用 add 命令所產(chǎn)生的也有垃圾對(duì)象,而這些垃圾對(duì)象怎么清除和回收呢?后續(xù),我們會(huì)涉及到的。

# 左邊執(zhí)行
$ echo "dev" > dev.txt
$ git add dev.txt
$ git commit -m "1st commit from dev branch"
$ git checkout master
$ git branch -d dev
$ git branch -D dev
$ git cat-file -t 861832c
$ git cat-file -p 861832c
$ git cat-file -p 680f6e9
$ git cat-file -p 38f8e88

# 右邊執(zhí)行
$ glo = git log

圖片

checkout 和 commit 操作

我們一起聊一聊,checkout 和 commit 的操作!

我們執(zhí)行 checkout 命令的時(shí)候,其不光可以切換分支,而且可以切換到指定的 commit 上面,即 HEAD 文件會(huì)指向某個(gè) commit 對(duì)象。在 Git 里面,將 HEAD 文件沒有指向 master 的這個(gè)現(xiàn)象稱之為 detached HEAD。

這里不管 HEAD 文件指向的是分支名稱也好,是 commit 對(duì)象也罷,其實(shí)本質(zhì)都是一樣的,因?yàn)榉种Q也是指向某個(gè) commit 對(duì)象的。

圖片

# 左邊執(zhí)行
$ git checkout 6e4a700
$ git log

# 右邊執(zhí)行
$ glo = git log

圖片

當(dāng)我們切換到指定的 commit 的時(shí)候,如果需要在對(duì)應(yīng)的 commit 上繼續(xù)修改代碼提交的話,可以使用上述圖片中提及的 swtich 命令創(chuàng)建新分支,再進(jìn)行提交。但是,通常我們都不會(huì)著玩,都會(huì)使用 checkout 命令來創(chuàng)建新分支的。

$ git checkout -b tmp
$ git log

即使可以這樣操作,我們也很少使用。還記得我們上一章節(jié)創(chuàng)建的 dev 分支嗎?我們創(chuàng)建了該分支并有了一個(gè)新的提交,但是沒有合并到 master 分支就直接刪除了?,F(xiàn)在再使用 log 命令查看的話,是看不到了。

實(shí)際,真的看不到了嗎?大家要記住,在 Git 里面任何的操作,比如分支的刪除。它只是刪除了指向某個(gè)特定 commit 的指針引用而已,而那個(gè) commit 本身并不會(huì)被刪除,即 dev 分支的那個(gè) commit 提交還是在的。

那我們?cè)趺凑业竭@個(gè) commit 呢?找到之后,我們就可以在上面繼續(xù)工作,或者找到之前的文件數(shù)據(jù)等。

第一種方法:

  • [費(fèi)勁不太好,下下策]
  • 在 objects 目錄下面,自己一個(gè)一個(gè)看,然后切換過去。

第二種方法:

  • [推薦的操作方式]
  • 使用 Git 提供的 git reflog 專用命令來查找。
  • 該命令的作用就是用于將我們之前的所有操作都記錄下來。

# 左邊執(zhí)行
$ git reflog
$ git checkout 9fb7a14
$ git checkout -b dev

# 右邊執(zhí)行
$ glo = git log

圖片

圖片

聊聊 diff 的執(zhí)行邏輯

當(dāng)我們執(zhí)行 diff 命令之后,Git 的邏輯它們是怎么對(duì)比出來的呢?

就在本節(jié)中中,我們使用上節(jié)的倉庫,修改文件內(nèi)容之后,看看 diff 命令都輸出了哪些內(nèi)容呢?我們這里一起來看看,研究研究!

$ echo "hello" > file1.txt
$ git diff
$ git cat-file -p 42d9955
$ git cat-file -p ce01362

# 下述命令原理也是一樣的
$ git diff --cached
$ git diff HEAD

圖片

Git 如何添加遠(yuǎn)程倉庫

如何將我們本地的倉庫和遠(yuǎn)程服務(wù)器上面的倉庫關(guān)聯(lián)起來呢?

初始化倉庫

$ git init
$ git add README.md
$ git commit -m "first commit"

關(guān)聯(lián)遠(yuǎn)程倉庫

當(dāng)我們使用上述命令來關(guān)聯(lián)遠(yuǎn)程服務(wù)器倉庫的時(shí)候,我們本地 .git 目錄也是會(huì)發(fā)生改變的。通過命令查看 .git/config 文件的話,可以看到配置文件中出現(xiàn)了 [remote] 字段。

# 關(guān)聯(lián)遠(yuǎn)程倉庫
$ git remote add origin git@github.com:escapelife/git-demo.git

? cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true

[remote "origin"]
url = git@github.com:escapelife/git-demo.git
fetch = +refs/heads/*:refs/remotes/origin/*

推送本地分支

當(dāng)我們執(zhí)行如下命令,將本地 master 分支推送到遠(yuǎn)程 origin 倉庫的 master 分支。之后,我們登陸 GitHub 就可以看到推送的文件及目錄內(nèi)容了。

推送分支內(nèi)容的時(shí)候,會(huì)列舉推送的 objects 數(shù)量,并將其內(nèi)容進(jìn)行壓縮,之后推送到我們遠(yuǎn)程的 GitHub 倉庫,并且創(chuàng)建了一個(gè)遠(yuǎn)程的 master 分支(origin 倉庫)。

# 推送本地分支
$ git push -u origin master

推送之后,我們可以發(fā)現(xiàn),本地的 .git 生成了一些文件和目錄,它們都是什么呢?如下所示,會(huì)新增四個(gè)目錄和兩個(gè)文件,皆為遠(yuǎn)程倉庫的信息。當(dāng)我們通過命令查看 master 這個(gè)文件的內(nèi)容時(shí),會(huì)發(fā)現(xiàn)其也是一個(gè) commit 對(duì)象。此時(shí)與我們本地 master 分支所指向的一致。而其用于表示遠(yuǎn)程倉庫的當(dāng)前版本,用于和本地進(jìn)行區(qū)別和校對(duì)的。

? tree .git
├── logs
│ ├── HEAD
│ └── refs
│ ├── heads
│ │ ├── dev
│ │ ├── master
│ │ └── tmp
│ └── remotes # 新增目錄
│ └── origin # 新增目錄
│ └── master # 新增文件
└── refs
├── heads
│ ├── dev
│ ├── master
│ └── tmp
├── remotes # 新增目錄
│ └── origin # 新增目錄
│ └── master # 新增文件
└── tags

遠(yuǎn)程倉庫存儲(chǔ)代碼

使用 GitLab 來了解遠(yuǎn)程倉庫的服務(wù)器到底是如何存儲(chǔ),我們的代碼的!

當(dāng)我們編寫完代碼之后,將其提交到對(duì)應(yīng)的遠(yuǎn)程服務(wù)器上面,其存儲(chǔ)結(jié)構(gòu)和我們地址是一模一樣的。如果我們仔細(xì)想想的話,不一樣的話才見怪了。

Git 本來就是代碼的分發(fā)平臺(tái),無中心節(jié)點(diǎn),即每個(gè)節(jié)點(diǎn)都是主節(jié)點(diǎn),所以其存儲(chǔ)的目錄結(jié)構(gòu)都是一直的。這樣,不管哪一個(gè)節(jié)點(diǎn)的內(nèi)容發(fā)生丟失或缺失的話,我們都可以通過其他節(jié)點(diǎn)來找到。而 Git 服務(wù)器就是一個(gè)可以幫助我們,實(shí)時(shí)都可以找到的節(jié)點(diǎn)而已。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • CVS
    CVS
    +關(guān)注

    關(guān)注

    0

    文章

    14

    瀏覽量

    10970
  • Git
    Git
    +關(guān)注

    關(guān)注

    0

    文章

    195

    瀏覽量

    15691
  • 版本管理
    +關(guān)注

    關(guān)注

    0

    文章

    4

    瀏覽量

    148
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    步進(jìn)電機(jī)基本原理

    本帖最后由 eehome 于 2013-1-5 09:48 編輯 步進(jìn)電機(jī)基本原理
    發(fā)表于 08-16 16:17

    擴(kuò)頻通信的基本原理

    附件非常詳解的介紹了擴(kuò)頻通信的基本原理,本人做通信快3年了,是我見過的介紹擴(kuò)頻通信最好的資料,分享一!
    發(fā)表于 11-15 10:57

    串聯(lián)諧振逆變器的基本原理

    串聯(lián)諧振通常伴有逆變器。該組合稱為串聯(lián)諧振逆變器。什么是基本原理?讓我簡(jiǎn)要介紹串聯(lián)諧振逆變器的一些基本原理。]首先給你看一張圖片:
    發(fā)表于 11-07 10:21

    IC測(cè)試基本原理是什么?

    IC測(cè)試基本原理是什么?ATE測(cè)試向量是什么?
    發(fā)表于 05-07 06:43

    IC測(cè)試的基本原理是什么?

    本文詳細(xì)介紹了芯片開發(fā)和生產(chǎn)過程中的IC測(cè)試基本原理
    發(fā)表于 05-08 07:33

    串口通信基本原理是什么

    目錄華大單片機(jī)---串口通信1.串口通信基本原理(1)串口通信原理:(2)華大的串口通信:(3)簡(jiǎn)單介紹:(4)多字符發(fā)送:2.初始化代碼3.發(fā)送代碼:4.接收中斷代碼華大單片機(jī)—串口通信1.串口
    發(fā)表于 07-14 07:26

    電機(jī)轉(zhuǎn)動(dòng)的基本原理是什么?

    電機(jī)轉(zhuǎn)動(dòng)的基本原理是什么?電機(jī)運(yùn)動(dòng)的基本原則有哪些?
    發(fā)表于 07-21 07:59

    線性電源的基本原理是什么

    多路線性電源 AC-DC穩(wěn)壓電源 低紋波電源 可調(diào)線性電源 原理圖PCB目錄多路線性電源 AC-DC穩(wěn)壓電源 低紋波電源 可調(diào)線性電源 原理圖PCB基本原理芯片選型原理圖&3D-PCB具體
    發(fā)表于 07-30 07:47

    無線充電的基本原理是什么

    一 、無線充電基本原理無線充電的基本原理就是我們平時(shí)常用的開關(guān)電源原理,區(qū)別在于沒有磁介質(zhì)耦合,那么我們需要利用磁共振的方式提高耦合效率,具體方法是在發(fā)送端和接收端線圈串并聯(lián)電容,是發(fā)送線圈處理諧振
    發(fā)表于 09-15 06:01

    RAID技術(shù)的基本原理是什么

    RAID技術(shù)的基本原理是什么?RAID技術(shù)有哪幾個(gè)優(yōu)勢(shì)?
    發(fā)表于 10-14 12:01

    IIC的基本原理是什么?

    IIC的基本原理是什么?
    發(fā)表于 11-25 08:46

    串口通信基本原理是什么?

    串口通信基本原理是什么?串行通信的分類有哪些?
    發(fā)表于 12-03 06:08

    串口通信的基本原理是什么?

    同步通信和異步通信的區(qū)別是什么?串口通信的基本原理是什么?
    發(fā)表于 12-13 06:46

    步進(jìn)馬達(dá)基本原理

    步進(jìn)馬達(dá)基本原理步進(jìn)馬達(dá)基本原理步進(jìn)馬達(dá)基本原理
    發(fā)表于 11-30 11:55 ?8次下載

    探究Git基本原理(上)

    簡(jiǎn)單地說,Git 究竟是怎樣的一個(gè)系統(tǒng)呢?請(qǐng)注意接下來的內(nèi)容非常重要,若你理解了 Git 的思想和基本工作原理,用起來就會(huì)知其所以然,游刃有余。 在學(xué)習(xí) Git 時(shí),請(qǐng)盡量理清你對(duì)其它版本管理
    的頭像 發(fā)表于 05-12 15:20 ?625次閱讀
    <b class='flag-5'>探究</b><b class='flag-5'>Git</b><b class='flag-5'>基本原理</b>(上)