吴忠躺衫网络科技有限公司

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

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

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

探究Git基本原理(下)

jf_78858299 ? 來源:分布式實驗室 ? 作者:分布式實驗室 ? 2023-05-12 15:20 ? 次閱讀

加深理解 commit 提交

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

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

# 左邊執(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)的,而且添加文件夾并不會增加 object 對象。當(dāng)我們查看 index 內(nèi)容的時候,會發(fā)現(xiàn)文件名稱是包含相對路徑的。

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

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

# 左邊執(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 的官方文檔,就可以得到,分支就是一個有名字的(master/dev)指向 commit 對象的一個指針。

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

圖片

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

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

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

圖片

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

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

圖片

分支操作的背后邏輯

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

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

# 左邊執(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

圖片

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

# 左邊執(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 命令的時候,其不光可以切換分支,而且可以切換到指定的 commit 上面,即 HEAD 文件會指向某個 commit 對象。在 Git 里面,將 HEAD 文件沒有指向 master 的這個現(xiàn)象稱之為 detached HEAD。

這里不管 HEAD 文件指向的是分支名稱也好,是 commit 對象也罷,其實本質(zhì)都是一樣的,因為分支名稱也是指向某個 commit 對象的。

圖片

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

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

圖片

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

$ git checkout -b tmp
$ git log

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

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

那我們怎么找到這個 commit 呢?找到之后,我們就可以在上面繼續(xù)工作,或者找到之前的文件數(shù)據(jù)等。

第一種方法:

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

第二種方法:

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

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

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

圖片

圖片

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

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

就在本節(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ù)器倉庫的時候,我們本地 .git 目錄也是會發(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)容的時候,會列舉推送的 objects 數(shù)量,并將其內(nèi)容進(jìn)行壓縮,之后推送到我們遠(yuǎn)程的 GitHub 倉庫,并且創(chuàng)建了一個遠(yuǎn)程的 master 分支(origin 倉庫)。

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

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

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

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

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

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

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

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

    關(guān)注

    0

    文章

    14

    瀏覽量

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

    關(guān)注

    0

    文章

    201

    瀏覽量

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

    關(guān)注

    0

    文章

    7

    瀏覽量

    187
收藏 人收藏

    評論

    相關(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)諧振逆變器。什么是基本原理?讓我簡要介紹串聯(lián)諧振逆變器的一些基本原理。]首先給你看一張圖片:
    發(fā)表于 11-07 10:21

    IC測試基本原理是什么?

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

    IC測試的基本原理是什么?

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

    TSP控制的基本原理是什么?

    TSP控制的基本原理是什么?
    發(fā)表于 05-11 06:39

    串口通信基本原理是什么

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

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

    電機(jī)轉(zhuǎn)動的基本原理是什么?電機(jī)運(yùn)動的基本原則有哪些?
    發(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

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

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

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

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

    IIC的基本原理是什么?

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

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

    同步通信和異步通信的區(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基本原理(上)

    簡單地說,Git 究竟是怎樣的一個系統(tǒng)呢?請注意接下來的內(nèi)容非常重要,若你理解了 Git 的思想和基本工作原理,用起來就會知其所以然,游刃有余。 在學(xué)習(xí) Git 時,請盡量理清你對其它版本管理
    的頭像 發(fā)表于 05-12 15:20 ?736次閱讀
    <b class='flag-5'>探究</b><b class='flag-5'>Git</b><b class='flag-5'>基本原理</b>(上)
    网上百家乐官网投注技巧| 皇马百家乐官网的玩法技巧和规则| 真博娱乐| 大发888老虎机下载| 百家乐赌场赌场网站| 免费百家乐官网倍投软件| 易球百家乐官网娱乐城| 东宁县| 赌神网百家乐官网的玩法技巧和规则 | 至尊百家乐官网20111110| 金冠娱乐城官网| 大发扑克官网| 梭哈棋牌游戏大厅| 百家乐娱乐备用网址| 百家乐发脾机| 宝马会百家乐的玩法技巧和规则 | 娱乐城排名| 温州市百家乐鞋业| 玩网上百家乐的技巧| 娱乐网百家乐补丁| 中国百家乐澳门真人娱乐平台网址| 江山百家乐的玩法技巧和规则| 如何玩百家乐的玩法技巧和规则| 丽星百家乐的玩法技巧和规则| 木星百家乐的玩法技巧和规则| 太阳城百家乐官网分析解码 | 百家乐官网币| 试玩百家乐官网代理| 利来百家乐官网的玩法技巧和规则 | 百家乐视频游365| 查看百家乐赌博| 百家乐建材| 百家乐真人娱乐场开户注册| 百家乐技巧看路| 三国百家乐的玩法技巧和规则| 大发888娱乐城真钱lm0| 南通棋牌游戏中心下载| 凯时百家乐官网技巧| 澳门百家乐官网鸿运| 凱旋门百家乐官网的玩法技巧和规则 | 免佣百家乐官网规则|