当前位置:   article > 正文

Git详解(带图) --- 本地电脑的工作区、暂存区、本地仓与远程仓_git 本地存储库与工作目录

git 本地存储库与工作目录

1. Introduction 介绍

在 git 的丰富功能中,工作区 (Work Space)、暂存区 (Index/Staging Area)、本地仓库 (Local Repository) 和远程仓库 (Remote Repository) 被认为是四大核心概念。今天让我们深入了解这些神秘的组成部分,揭开它们的面纱,让你能够更好地利用Git来管理项目。

上图相信大家再熟悉不过,这是我从 Git 基本操作 | 菜鸟教程 直接贴过来的,网上也有很多类似的图解...这个关系图主要介绍这四个区之间的关系,以及它们之间的 git 基本操作命令。在这个的基础上我将结合不同的文件、目录重点解释:workspace、staging area、local repository 到底存在我们自己电脑的何处,以及它们内部是如何关联运转的。希望看完你能有所收获。


2. Basic Concept 基本概念

工作区 (Work Space):是在电脑文件系统中能看到的项目目录。它包含项目的实际文件,你在工作区进行的修改会影响到这些文件。比如,你新创建了一个文件夹,git init 命令以后它就成为了一个 git 目录,然后你在文件夹里修改了一个 readme.txt 文件,也就是所谓的在工作区修改了它,这个很好理解。

暂存区 (Index/ Staging Area):是一个中间区域,用于暂存工作区中的改动,但这些改动还没有提交到本地仓库。在进行版本控制时,你需要明确地将修改添加到暂存区,这相当于一次“快照”,在提交到本地仓库之前,你可以对这次“快照”进行进一步的调整。这个区域比较抽象,我们暂时不需要看到它,只用记住在提交到本地仓之前,先添加到这儿就行

本地仓库 (Local Repository):是存储在自己计算机本地的版本库,包含了完整的项目历史数据。执行 git commit 命令后会将暂存区的内容添加到这里,git 会保存为一个新的提交,并更新本地仓库,这样就形成了项目的版本历史。这个区域也比较抽象,暂时不用担心

远程仓库 (Remote Repository):是位于网络上的 git 仓库,通常托管在像 GitHub、GitLab 或 Bitbucket 等服务提供商上。远程仓库用于协作和备份。多个开发者可以共享同一个远程仓库,每个人可以将自己的改动推送到远程仓库,从而实现协同开发。同时,远程仓库也提供了项目的备份和存档。


3. Further Exploration 进一步探索

其实,在我们的电脑上,git 工作区是工作区、暂存区和本地仓的统称...现在我们用图文形式开始解释,以 Mac 电脑为例,Windows 基本思路一致。

3.1 Git Structure 文件结构

首先我们从 git 文件夹结构入手,比如我们创建了一个文件夹 learnGit 并且使用 git init 命令初始化成一个 git 文件夹,里面有一个 readme.txt 文件,那么 readme.txt 其实就处在该 git 文件夹的工作区,这点很好理解对吧。

此时如果我们在 learnGit 目录中使用 command + shift + . 快捷键 (显示隐藏文件),会出现一个 .git 文件夹,这就是我们所谓的本地版本库,它是 git 版本控制系统用于存储仓库元数据和对象的目录,更是 git 的核心。它包含了 git 仓库的全部信息,包括版本历史、分支、标签、配置等。

3.2 Key folder 隐藏文件 .git

.git 文件夹是Git版本库的核心,它使得Git能够追踪文件的更改、管理分支、记录提交历史等。这个文件夹通常位于项目的根目录下。在通常情况下,用户不太需要直接操作这个文件夹,而是通过Git命令来与版本库进行交互。为了更好地了解 git,一起来看看以下几个重要的文件及文件夹。

3.2.1 index 文件

没错,通过名字不难看出 index 文件实际上就存储了将被包含在下一次提交中的文件信息,我们可以理解为这就是 Staging Area 即暂存区的内容。这就是为什么说暂存区的内容其实也被包括在工作区

3.2.2 HEAD 文件 (*)

指向当前所在分支的最新提交,当前表明我们在本地的 main 分支,如果我们切换到另一本地分支,比如 temp,那么这个 HEAD 文件就会显示 ref: refs/heads/temp (之后演示的内容原理都和 main 分支一样)。HEAD 文件的内容是一个路径文件,我们打开这个路径下的main文件 .git/refs/heads/main

显示为一段 hash 码,我们先不要关掉这个文件,等下看这个 hash 码和谁能对应上

3.2.3 logs 文件夹 (*)

由文件夹名字不难看出这是一个用于存放记录日志的目录,logs 文件夹下又包括一个 HEAD 以及 refs 文件夹,如下图所示

与上一个 HEAD 文件不同,这个 HEAD 文件在 logs 文件夹下,它主要记录的是 'HEAD' 引用的变化,即当前所在的分支或提交的变化。可用于记录分支切换,版本回退,提交等日志。比如每次切换分支或提交时,都会在这个文件中生成一条记录,包括变化的时间、旧的 HEAD 引用的位置、新的 HEAD 引用的位置等信息。

refs 文件夹中包含 heads 和 remotes 两个文件夹,remotes 很明显是关于远程仓的,我们主要来看看 heads。heads 文件夹中包含一个 main 文件。这个文件是用于记录本地特定分支的引用变化,每次该分支发生变化时,都会在这个文件中生成一条记录,包括变化的时间、旧的分支位置、新的分支位置等信息。

我们用文本编辑器打开这个 .git/logs/refs/heads/main 文件

我们发现最后的 hash 码和之前那个对应上了! 

.git/HEAD 指向的 .git/refs/heads/main 哈希码 == .git/logs/refs/heads/main 最后的哈希码

我们知道 HEAD 表示当前分支提交的最新版本,上面这个例子表示,我们目前所在的本地 main 分支上最新提交版本对应的 reference (快照) 是 ece57b94dd97a....5896 这个 Hash 码,由此我们得出结论,在获取历史提交版本时是以 commit 对应的 Hash 码作为依据找到对应的提交版本,这个 Hash 码在 .git/logs 日志中可以找到。 

可是,有了 Hash 码还不够,我们还要根据这个 Hash 码找到具体的提交内容,那么具体的提交内容存放在哪呢?

3.2.4 objects 文件夹 (*)

objects 就是我们的本地对象库,它的作用是存储所有的 git 对象,如提交内容、树(目录)、Blob(文件)等。所以如果我们要依据 Hash 码找到实际的提交内容,就要拿着 logs 文件夹中存储的 Hash 码来 objects 文件夹取。在这个目录中,git 会根据哈希值的前两个字符将对象分组存储。每个提交对象的内容会被压缩、存储在一个以哈希值命名的文件中。如果对象内容有变化,git 会生成新的哈希值。

打开这个 ec 文件夹就能看到,我们最后一次提交的具体内容了,这个内容是以之前那个 Hash 码命名的。很巧的是,我们上一次的提交和最新的提交 Hash 码开头差不多,所以 git 通过计算前两位 hash 码将两者都放在了这个文件夹中。


4. Conclusion 总结

到此我们就知道了工作区、暂存区、本地仓库在自己的电脑到底是如何存在的,以及他们之间是如何运作产生联系的,本地仓库就是 .git/objects 文件夹,暂存区就是 index,HEAD 指向当前本地分支最新的提交,这个提交对应有一个 commit id, 以 Hash 值表示,获取或者推送某个提交需要拿着 Hash 值去本地仓库也就是 .git/objects 里找到具体的提交内容。

4.1 关系图

下图是我总结出的工作区、暂存区及本地版本仓库的关系图 (以本地 learnGit 为例),供大家参考。

感谢各位的阅读,如果你觉得我的博客对你有所帮助或启发,欢迎点赞收藏 本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/581900

推荐阅读
相关标签