1. Introduction 介紹
在 git 的豐富功能中,工作區(qū) (Work Space)、暫存區(qū) (Index/Staging?Area)、本地倉(cāng)庫(kù) (Local Repository) 和遠(yuǎn)程倉(cāng)庫(kù) (Remote Repository) 被認(rèn)為是四大核心概念。今天讓我們深入了解這些神秘的組成部分,揭開(kāi)它們的面紗,讓你能夠更好地利用Git來(lái)管理項(xiàng)目。
上圖相信大家再熟悉不過(guò),這是我從?Git 基本操作 | 菜鳥(niǎo)教程?直接貼過(guò)來(lái)的,網(wǎng)上也有很多類似的圖解...這個(gè)關(guān)系圖主要介紹這四個(gè)區(qū)之間的關(guān)系,以及它們之間的 git 基本操作命令。在這個(gè)的基礎(chǔ)上我將結(jié)合不同的文件、目錄重點(diǎn)解釋:workspace、staging area、local repository 到底存在我們自己電腦的何處,以及它們內(nèi)部是如何關(guān)聯(lián)運(yùn)轉(zhuǎn)的。希望看完你能有所收獲。
2. Basic Concept 基本概念
工作區(qū) (Work Space):是在電腦文件系統(tǒng)中能看到的項(xiàng)目目錄。它包含項(xiàng)目的實(shí)際文件,你在工作區(qū)進(jìn)行的修改會(huì)影響到這些文件。比如,你新創(chuàng)建了一個(gè)文件夾,git init 命令以后它就成為了一個(gè) git 目錄,然后你在文件夾里修改了一個(gè) readme.txt 文件,也就是所謂的在工作區(qū)修改了它,這個(gè)很好理解。
暫存區(qū) (Index/ Staging Area):是一個(gè)中間區(qū)域,用于暫存工作區(qū)中的改動(dòng),但這些改動(dòng)還沒(méi)有提交到本地倉(cāng)庫(kù)。在進(jìn)行版本控制時(shí),你需要明確地將修改添加到暫存區(qū),這相當(dāng)于一次“快照”,在提交到本地倉(cāng)庫(kù)之前,你可以對(duì)這次“快照”進(jìn)行進(jìn)一步的調(diào)整。這個(gè)區(qū)域比較抽象,我們暫時(shí)不需要看到它,只用記住在提交到本地倉(cāng)之前,先添加到這兒就行。
本地倉(cāng)庫(kù) (Local Repository):是存儲(chǔ)在自己計(jì)算機(jī)本地的版本庫(kù),包含了完整的項(xiàng)目歷史數(shù)據(jù)。執(zhí)行 git commit 命令后會(huì)將暫存區(qū)的內(nèi)容添加到這里,git 會(huì)保存為一個(gè)新的提交,并更新本地倉(cāng)庫(kù),這樣就形成了項(xiàng)目的版本歷史。這個(gè)區(qū)域也比較抽象,暫時(shí)不用擔(dān)心。
遠(yuǎn)程倉(cāng)庫(kù) (Remote Repository):是位于網(wǎng)絡(luò)上的 git 倉(cāng)庫(kù),通常托管在像 GitHub、GitLab 或 Bitbucket 等服務(wù)提供商上。遠(yuǎn)程倉(cāng)庫(kù)用于協(xié)作和備份。多個(gè)開(kāi)發(fā)者可以共享同一個(gè)遠(yuǎn)程倉(cāng)庫(kù),每個(gè)人可以將自己的改動(dòng)推送到遠(yuǎn)程倉(cāng)庫(kù),從而實(shí)現(xiàn)協(xié)同開(kāi)發(fā)。同時(shí),遠(yuǎn)程倉(cāng)庫(kù)也提供了項(xiàng)目的備份和存檔。
3. Further Exploration 進(jìn)一步探索
其實(shí),在我們的電腦上,git 工作區(qū)是工作區(qū)、暫存區(qū)和本地倉(cāng)的統(tǒng)稱...現(xiàn)在我們用圖文形式開(kāi)始解釋,以 Mac 電腦為例,Windows 基本思路一致。
3.1 Git Structure 文件結(jié)構(gòu)
首先我們從 git 文件夾結(jié)構(gòu)入手,比如我們創(chuàng)建了一個(gè)文件夾 learnGit 并且使用 git init 命令初始化成一個(gè) git 文件夾,里面有一個(gè) readme.txt 文件,那么 readme.txt 其實(shí)就處在該 git 文件夾的工作區(qū),這點(diǎn)很好理解對(duì)吧。
此時(shí)如果我們?cè)?learnGit 目錄中使用 command + shift + . 快捷鍵 (顯示隱藏文件),會(huì)出現(xiàn)一個(gè) .git 文件夾,這就是我們所謂的本地版本庫(kù),它是 git 版本控制系統(tǒng)用于存儲(chǔ)倉(cāng)庫(kù)元數(shù)據(jù)和對(duì)象的目錄,更是 git 的核心。它包含了 git 倉(cāng)庫(kù)的全部信息,包括版本歷史、分支、標(biāo)簽、配置等。
3.2 Key folder?隱藏文件 .git
.git
文件夾是Git版本庫(kù)的核心,它使得Git能夠追蹤文件的更改、管理分支、記錄提交歷史等。這個(gè)文件夾通常位于項(xiàng)目的根目錄下。在通常情況下,用戶不太需要直接操作這個(gè)文件夾,而是通過(guò)Git命令來(lái)與版本庫(kù)進(jìn)行交互。為了更好地了解 git,一起來(lái)看看以下幾個(gè)重要的文件及文件夾。
3.2.1 index 文件
沒(méi)錯(cuò),通過(guò)名字不難看出 index 文件實(shí)際上就存儲(chǔ)了將被包含在下一次提交中的文件信息,我們可以理解為這就是 Staging Area 即暫存區(qū)的內(nèi)容。這就是為什么說(shuō)暫存區(qū)的內(nèi)容其實(shí)也被包括在工作區(qū)。
3.2.2?HEAD 文件?(*)
指向當(dāng)前所在分支的最新提交,當(dāng)前表明我們?cè)诒镜氐?main 分支,如果我們切換到另一本地分支,比如 temp,那么這個(gè) HEAD 文件就會(huì)顯示 ref: refs/heads/temp?(之后演示的內(nèi)容原理都和 main 分支一樣)。HEAD 文件的內(nèi)容是一個(gè)路徑文件,我們打開(kāi)這個(gè)路徑下的main文件 .git/refs/heads/main
顯示為一段 hash 碼,我們先不要關(guān)掉這個(gè)文件,等下看這個(gè) hash 碼和誰(shuí)能對(duì)應(yīng)上
3.2.3 logs 文件夾?(*)
由文件夾名字不難看出這是一個(gè)用于存放記錄日志的目錄,logs 文件夾下又包括一個(gè) HEAD 以及 refs 文件夾,如下圖所示
與上一個(gè) HEAD 文件不同,這個(gè) HEAD 文件在 logs 文件夾下,它主要記錄的是 'HEAD'?引用的變化,即當(dāng)前所在的分支或提交的變化??捎糜谟涗浄种袚Q,版本回退,提交等日志。比如每次切換分支或提交時(shí),都會(huì)在這個(gè)文件中生成一條記錄,包括變化的時(shí)間、舊的 HEAD
引用的位置、新的 HEAD
引用的位置等信息。
refs 文件夾中包含 heads 和 remotes 兩個(gè)文件夾,remotes 很明顯是關(guān)于遠(yuǎn)程倉(cāng)的,我們主要來(lái)看看 heads。heads 文件夾中包含一個(gè) main 文件。這個(gè)文件是用于記錄本地特定分支的引用變化,每次該分支發(fā)生變化時(shí),都會(huì)在這個(gè)文件中生成一條記錄,包括變化的時(shí)間、舊的分支位置、新的分支位置等信息。
我們用文本編輯器打開(kāi)這個(gè) .git/logs/refs/heads/main 文件
我們發(fā)現(xiàn)最后的 hash 碼和之前那個(gè)對(duì)應(yīng)上了!?
.git/HEAD 指向的?.git/refs/heads/main 哈希碼 ==?.git/logs/refs/heads/main 最后的哈希碼
我們知道 HEAD 表示當(dāng)前分支提交的最新版本,上面這個(gè)例子表示,我們目前所在的本地?main 分支上最新提交版本對(duì)應(yīng)的 reference (快照) 是 ece57b94dd97a....5896 這個(gè) Hash 碼,由此我們得出結(jié)論,在獲取歷史提交版本時(shí)是以?commit 對(duì)應(yīng)的 Hash 碼作為依據(jù)找到對(duì)應(yīng)的提交版本,這個(gè) Hash 碼在 .git/logs 日志中可以找到。?
可是,有了 Hash 碼還不夠,我們還要根據(jù)這個(gè) Hash 碼找到具體的提交內(nèi)容,那么具體的提交內(nèi)容存放在哪呢?
3.2.4 objects 文件夾?(*)
objects 就是我們的本地對(duì)象庫(kù),它的作用是存儲(chǔ)所有的 git 對(duì)象,如提交內(nèi)容、樹(shù)(目錄)、Blob(文件)等。所以如果我們要依據(jù) Hash 碼找到實(shí)際的提交內(nèi)容,就要拿著 logs 文件夾中存儲(chǔ)的?Hash 碼來(lái) objects 文件夾取。在這個(gè)目錄中,git 會(huì)根據(jù)哈希值的前兩個(gè)字符將對(duì)象分組存儲(chǔ)。每個(gè)提交對(duì)象的內(nèi)容會(huì)被壓縮、存儲(chǔ)在一個(gè)以哈希值命名的文件中。如果對(duì)象內(nèi)容有變化,git 會(huì)生成新的哈希值。
打開(kāi)這個(gè) ec 文件夾就能看到,我們最后一次提交的具體內(nèi)容了,這個(gè)內(nèi)容是以之前那個(gè) Hash 碼命名的。很巧的是,我們上一次的提交和最新的提交 Hash 碼開(kāi)頭差不多,所以 git 通過(guò)計(jì)算前兩位 hash 碼將兩者都放在了這個(gè)文件夾中。
4. Conclusion 總結(jié)
到此我們就知道了工作區(qū)、暫存區(qū)、本地倉(cāng)庫(kù)在自己的電腦到底是如何存在的,以及他們之間是如何運(yùn)作產(chǎn)生聯(lián)系的,本地倉(cāng)庫(kù)就是 .git/objects 文件夾,暫存區(qū)就是 index,HEAD 指向當(dāng)前本地分支最新的提交,這個(gè)提交對(duì)應(yīng)有一個(gè) commit id, 以 Hash 值表示,獲取或者推送某個(gè)提交需要拿著 Hash 值去本地倉(cāng)庫(kù)也就是 .git/objects 里找到具體的提交內(nèi)容。
4.1 關(guān)系圖
下圖是我總結(jié)出的工作區(qū)、暫存區(qū)及本地版本倉(cāng)庫(kù)的關(guān)系圖 (以本地 learnGit 為例),供大家參考。
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-802263.html
感謝各位的閱讀,如果你覺(jué)得我的博客對(duì)你有所幫助或啟發(fā),歡迎點(diǎn)贊收藏??~文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-802263.html
到了這里,關(guān)于Git詳解(帶圖) --- 本地電腦的工作區(qū)、暫存區(qū)、本地倉(cāng)與遠(yuǎn)程倉(cāng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!