git merge原理,-m commit git_Git 天天用,但是 Git 原理你了解嗎?不進來了解一下?

 2023-10-07 阅读 18 评论 0

摘要:前言做技術一定要知其然知其所以然,意思就是:知道它是這樣的,更知道它為什么是這樣的。我主要通過4塊內容來簡單介紹 Git 原理是什么樣的。這4塊內容如下:Git 存儲目錄結構介紹Git 是如何存儲的Git 的對象Git引用git merge原理,當然 Git 原理不僅

前言

做技術一定要知其然知其所以然,意思就是:知道它是這樣的,更知道它為什么是這樣的。我主要通過4塊內容來簡單介紹 Git 原理是什么樣的。這4塊內容如下:

  • Git 存儲目錄結構介紹
  • Git 是如何存儲的
  • Git 的對象
  • Git引用

git merge原理,當然 Git 原理不僅僅包含這些,想要更深入了解請查看官方教程 https://git-scm.com/book/zh/v2/。

本文內容是我在 GitChat 分享關于Git 的Chat 《Git實用操作手冊》 摘抄一個章節,關于《Git實用操作手冊》其他內容請訪問 https://gitbook.cn/gitchat/activity/5cb46e9dd877c443a183f9d4。

Git 存儲目錄結構介紹

首先我們先從 Git 存儲目錄說起,通過 git init 創建一個空的 Git 倉庫,具體操作如下圖:

091226c23c660d0f39830efd0f10212d.png

創建完成后進入 .git 目錄,如下圖所示:

7beed7ec51d2135dcd3b8a77bc9d5478.png
  • hooks 該目錄用于配置 客戶端執提交操作用于觸發服務端的腳本配置,一般用于自動化部署使用
  • info 該目錄用于配置一些不希望被 Git 管控的文件。
  • objects 該目錄用于存儲所有數據對象內容,這些數據內容類型有 commit tree blob tag
  • refs 該目錄用于存儲 Git 本地以及遠程分支的引用,當然還有一種特殊的引用標簽引用
  • config 該文件包含項目特有的配置選項,并且該配置僅對該 Git 倉庫有效
  • description 該文件僅供 GitWeb 程序使用
  • HEAD 該文件表示當前 Git 倉庫處于哪個分支
  • index 該文件保存暫存區信息 (空倉庫下該文件不會顯示一旦執行 git add 操作該文件就會出現)

通過 git config --local 查看 config 文件的變化

我們通過 git config --local 配置僅對于 gitLearn 項目有效,用戶名和郵箱配置如下圖所示:

803b09d05a6ece09fc0a7a8c75558a27.png

查看 config 文件,會發現該文件新增用戶信息配置。

Git 是如何存儲的

Git 是一個內容尋址文件系統 其核心部分是一個簡單的鍵值對數據庫(key-value data store)。 你可以向該數據庫插入任意類型的內容,它會返回一個 40 位字符串鍵,通過該 40 位字符串鍵可以在任意時刻再次檢索(retrieve)該內容。

什么是內容尋址?

每次我們進行提交會通過 SHA-1 算法生成一個長度為 40 個字符的校驗和(checksum hash)(也就是我們的 key)然后根據校驗和去獲取我們文件的內容。這種通過唯一標識的 key(也可以理解為內容的地址)去獲取我們的內容的操作就是內容尋址。

Git 的對象

在 Git 中有四種對象分別為:

  • blob 是具體的文件對象
  • tree 是某個時刻提交目錄的內容
  • commit 執行一次 commit 就會產生一個 commit 對象
  • tag 可以理解成 commit 的別名,一個 tag 對應一個 commit

了解 Git 的對象需要使用如下命令進行查看:

  • git cat-file -p 對象 hash 值 查看對象的內容
  • git cat-file -t 對象 hash值 查看對象的類型
  • git ls-files --stage 查看 index 文件內容
  • git hash-object 查看文件的 hash 值

查看 commit tree blob 三個對象演示

我們創建一個 first.txt 文件,并將其提交到暫存區中。

進入 .git 文件夾下會發現新增了一個 index 文件。

10ec9699f181756c5199bcbca469c744.png

我們可以通過 git ls-files --stage 查看 index 文件的內容。

cc8327a4143348b2b1e2767c8abc4945.png

進入 objects 目錄發現 9c 文件夾名稱+文件名稱 和 index 文件中的一段字符串內容相同。

6668a63cd8659743a26a326f7ef56c70.png

我們通過 git cat-file -t 9c59e24b8393179a5d712de4f990178df5734d99 我查看該表示對象類型 如下圖所示表示該標識對象類型是 blob。

5ff22639938c638fde27ae1ed0b09f0a.png

執行 git commit -m 將 first.txt 文件提交到本地倉庫中。

1cffe0f5446ce230d1006242f5e82b3c.png

執行 git log 查看我們的提交記錄。

83e5408a00e99cf9a98275ec7351079b.png

如下圖所示我們通過 git cat-file -p commitId 查看我們提交的內容。如下圖所示:我們最新一次提交包含了一個 59b06 開頭的 tree 對象。

f1e28e45088fb37221fdf552a12d464e.png

在 ./git/objects 目錄中可以找到我們對應的文件。

我們通過 git cat-file -p tree對象哈希值,查看該 tree 對象的內容 。如下圖所示顯示就是我們 git add參生的 blob對象。

在通過 git cat-file -p blob對象哈希值,查看我們 blob對象內容,如下圖所示 blob對象 內容就是我們 first.txt 文件的內容。

aa305b5594d87a4c521729a59313ccf0.png

我們將 first.txt 文件提交到本地倉庫 會產生一個 commit 一個 tree 和一個 blob 對象。

tag 對象原理演示

首先我們通過 git log 查看最新的提交是 add a.txt 注釋的 commit 如下圖所示。

ce6db56a999451129cb658d7a4c6bcde.png

通過 git tag -a v1.1 -m ‘add a.txt tag’ 為該 commit 創建一個附注標簽。

7396baeb86f53d95a130835754d0bf5a.png

在我們的 .git/refs/tags/ 目錄下會新增 v1.1 文件。

v1.1 內容如下:

aee5d0e43d8ce24b358cd591e485bf7e.png

看到這個你肯定想到了這是一個 Git 對象,我們通過 git cat-file -t 查看這個哈希值對象類型。如下圖所示它是一個 tag。

ce3f759b5d5bc31cf2e1876e3a379d4a.png

然后通過 git cat-file -p 查看它的內容,如下圖所示,該tag包含了commit 對象和 標注的信息。

9e109c8be16b4533fab0f87e210461c3.png

Git 引用

什么是 Git 的引用?

這里的引用我們可以理解成一個書簽,你在閱讀一本書的時候可以為你讀到的部分打上標簽。然后你可以通過這個書簽快速找到你之前閱讀的位置。在 Git 中我們 創建新的 Commit 或者創建分支都會進行一次打標簽的操作。我們各個不同 commit 之間的切換或分支的切換其實就是標簽的切換。

Git 引用的三種類型

在 Git 中有三種類型的的引用 分別是:

  • HEAD 引用:用來為我們的本地倉庫打上標簽使用。
  • Tag 引用:用來為我們的 Git 倉庫 tag 標簽使用。
  • 遠程引用:用來為我們的遠程倉庫打標簽使用。

HEAD 引用

HEAD 引用原理 我的個人理解是一個 Head 頭指針+當前分支 指向當前最新提交的 commit 對象。我們也可以通過 git reset --hard 來切換我們commit 記錄,切換后的 commit 以前的 commit 記錄就沒有了,不過我們可以通過 git reflog 查詢操作記錄將以前 commit 找回。

為了更好的理解 HEAD,引用建議大家訪問 http://onlywei.github.io/explain-git-with-d3/#zen 執行 Git 相關的操作來理解什么是 HEAD引用。

如下圖所示,我們的 Head頭指針分支 指向 master分支 同時指向最新的 commit e137e。

5ed210a89c92974e797e8c176dbc2224.png

我們執行一次 commit Head頭指針分支 + master分支 就指向的是最新的提交 896ee 上。

31df6ccba03c62f78fc3e7937e508001.png

通過 git branch b1 創建新的分支名稱為b1,如下圖所示,我們發現 Head 頭指針還是指向 master 。

7391564ce95385f62e49f37f7c2372dc.png

當執行 git checkout b1 的時候,如下圖所示,此時 Head 指針指向分支 b1。

cea8e6e099082f3e828ba7e0ac15106c.png

我們在分支 b1 上執行 commit Head 指針指向了在該分支下的最新提交 3c7acb。

281e652d23a30d1304bb636b700cae42.png

當執行 git checkout master 是 Head 指針指向了 master 上最新的 commit 896ee。

b443af7073ee7a2586ca0f07abed66ac.png

當執行 git merge b1 的時候,會將 b1分支最新 commit 合并到 master,我們 Head指針 + master 同時指向最新的 commit 3c7ba 上。

61a3e516bd59b5c739ea98abedc9d65e.png

通過上面的動態演示,這回對 Head 應用如何切換 commit 切換分支有了一定的理解。

這里非常建議你自己通過訪問

http://onlywei.github.io/explain-git-with-d3/#zen

來親自體驗一下。

接下來我們來通過查看 .git 目錄來介紹 Head 指針是如何實現的。進入 .git 目錄你會發現有一個 HEAD 文件,它的內容是 ref: refs/heads/master,如下圖所示。

4a4ea2c0ea745ab4435bbf533ab4e86b.png
eefb12885823e626f90132a0d7a68e51.png

refs/heads/master 是具體文件路徑,我們查 refs/heads 目錄下的 master 文件內容,如下圖所示,master 文件內容就是我們最新的 commit。

798137bee394a085ec47adbd9932d93a.png
69d45ec440ac912ac19bf16bd24c456d.png
f8ffe59184b43b48b28c5c95e69f548c.png

我們執行 git chekcout demoBranch3。

8612a8ba21c1e2980dcbc384ef241cca.png
373510eae95ebbacfb244d009d9679e4.png

此時我們的 HEAD 文件內容變成了 ref: refs/heads/demoBranch3。

查看 refs/heads/ 路徑下的 demoBranch3 文件,如下圖所示 demoBranch3 文件記錄是demoBranch3 分支下最新的 commit。

e1e392fa87aa81c81d5a23582d94d98c.png
befa965e68fbe0151101ee57c2ae150a.png

標簽引用

標簽引用是一個特殊的引用,它不像 HEAD 引用可以通過 git checkout 來更改引用的指針指向。標簽引用不會移動它永遠會指向一個 Commit 對象。

標簽引用的演示請參看 Tag 對象原理演示部分。

遠程引用

遠程引用是只讀的我們不能通過切換到遠程引用執行 commit 將提交更新到遠程倉庫中

我們在本地分支執行 push 操作,Git 都會幫我們記錄 push 到遠程分支的最新 comit,當執行push 的時候,如果發現遠程分支最新 commit 和我們本地倉庫記錄最后一次 push 的 commit 不同會報 Note about fast-forwards 異常,如下圖所示:

3071d856df0c3db5314d1145649d0d74.png

出現 Note about fast-forwards 我們需要執行 git pull 將遠程最新的 commit 拉取下來 然后再執行 git push 操作 或者 直接執行 git puhs -f。這里強調一下不建議執行 git puhs -f 操作因為會強制將本地的歷史記錄覆蓋到遠程倉庫的歷史記錄。

通過查看 .git 目錄理解遠程引用

在 .git/refs/remotes/origin 文件夾中 HEAD 文件內容表示內容表示遠程分支處于哪個分支。

1e46c06998e41e65203a7e5f55c74b55.png

在 .git/refs/remotes/origin 文件夾中 master 文件內容,表示最后一次 push 到遠程倉庫的commit,如下圖所示:

0e4553a0939f52bd61a4e7ac7c68d4f4.png
cba564f80b72be84b5d4a5d01c1dad1e.png

在 .git/refs/remotes/origin 文件夾中 demoBranch1 文件表示,最后一次 push 到 demoBranch1 分支提交的 commitId。

e7cac6b1b35fef24df373dd323a5aa27.png

原文鏈接:https://blog.csdn.net/ljk126wy/article/details/101064186

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/4/128455.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息