探秘 Git 底层原理:明白版本控制的基石

打印 上一主题 下一主题

主题 1820|帖子 1820|积分 5460

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Git 是一款开源的分布式版本控制体系,在软件开发领域广泛应用,能有用管理项目的版本变更,Git 已经成为了版本控制的代名词。日常使用中,我们通过git commit提交代码,用git push推送变更,这些便捷操作背后,是 Git 精巧的底层原理在支撑。相识 Git 底层原理,不仅能让我们更深入地明白版本控制的本质,还能在遇到复杂题目时快速定位和办理。本文将着重介绍git基础的底层知识
  一.分布式版本控制与集中式版本控制



  • 分布式版本控制体系:每个开发者的本地环境都有完整的项目仓库副本,包含全部的提交历史、分支信息等。这意味着开发者可以在本地举行各种操作,如提交、检察历史纪录等,无需依靠网络毗连到中央服务器。
  • 集中式版本控制体系:存在一个中央服务器,它是全部版本数据的唯一存储地。各个客户端必要从中央服务器获取最新版本的文件举行操作。比方,一个软件开发团队使用 SVN (集中式版本控制体系)举行版本控制,全部的代码都存放在中央服务器上,开发职员在本地修改代码后,必要将修改提交到中央服务器
简单来说,集中式的核心操作(提交,更新等)都必要和中央服务器举行交互,而分布式更加灵活,使用者可以在本地举行独立开发,然后通过推送和拉取操作与其他成员的仓库举行同步
二、Git 的对象存储:数据的基石

Git 将全部数据都存储为对象,主要有三种范例:blob 对象、tree 对象和commit 对象。
2.1 Blob 对象

Blob(Binary Large Object)对象用于存储文件内容,它是 Git 中最基础的数据单元。当我们在工作目次中创建或修改一个文件,Git 会为该文件的内容生成一个唯一的哈希值,并将文件内容存储为一个 Blob 对象。比方,创建一个名为test.txt的文件,内容为 “Hello, Git!”,Git 会根据内容计算出一个 40 位的 SHA-1 哈希值(如2c7b42d07a4e5e8c8c8b4c9f7a9a7a7d8d8c7b2a),并将文件内容以 Blob 对象的情势存储在.git/objects目次下。值得注意的是,Blob 对象只包含文件内容,不包含文件名、文件权限等元数据 ,因此当一个文件夹中有多份相同内容的文件,由于其哈希值相同,那么只会有一个对应的blob对象。(相当于文件数据的哈希值)使用git ls-tree HEAD可以看到目次下全部blob对象。
2.2 Tree 对象

Tree 对象用于存储目次结构和文件信息,它相当于一个目次索引。一个 Tree 对象可以包含多个子 Tree 对象和 Blob 对象的引用,以及它们对应的文件名和权限信息。比方,一个项目目次下有src目次和README.md文件,src目次下又有main.js文件,Git 会创建一个顶级 Tree 对象,此中包含指向src子 Tree 对象和README.md对应的 Blob 对象的引用,src子 Tree 对象则包含指向main.js对应的 Blob 对象的引用。通过这种层级结构,Git 能够精确纪录整个项目的目次和文件状态 。(可以把Tree明白为一个文件夹)
2.3 Commit 对象

Commit 对象代表一次提交,它包含了提交的元数据,如作者信息、提交时间、提交消息,以及一个指向本次提交根 Tree 对象的指针,用于纪录提交时项目的状态。此外,Commit 对象还可以包含一个或多个父 Commit 对象的指针,用于表现提交之间的关系。单分支上的提交链,就是通过 Commit 对象的父指针串联起来的;而归并提交则会有多个父 Commit 对象,以此反映归并操作 。
示例

假设你有一个包含两个文件(file1.txt和file2.txt)的项目。在对这两个文件举行修改并将它们添加到暂存区后,实验git commit -m "Update files"下令。Git 会为file1.txt和file2.txt的新内容分别创建 Blob 对象,根据项目目次结构创建 Tree 对象来引用这两个 Blob 对象,最后创建一个 Commit 对象指向该 Tree 对象,并纪录提交元数据(修改者,提交时间,父commit哈希值)。此后,若必要检察此次提交时项目的状态,只需找到对应的 Commit 对象即可。
tips

一般来说,每次commit都会产生一个新的tree对象,但是假如暂存区没有发生变革,即没有文件内容或结构的变革,在commit之后新的commit对象就会指向上一次提交对应的Tree,不会额外产生一个新Tree对象。
三、引用管理:高效定位对象

Git 使用引用(Reference)来方便地定位和操作对象。常见的引用范例有分支引用和标签引用。
3.1 分支引用

在 Git 中,分支本质上是一个指向 Commit 对象的可变指针。默认的主分支master(或main),以及我们创建的其他分支,都是通过一个以refs/heads/开头的文件来存储指向最新 Commit 对象的哈希值。比方,refs/heads/main文件中存储的就是当前main分支最新提交的 Commit 对象的哈希值。当我们举行提交操作时,对应的分支指针会自动指向新的 Commit 对象,而其他分支不受影响,这使得 Git 能够轻松实现并行开发 。
3.2 标签引用

标签引用与分支引用雷同,但标签一旦创建,通常不会改变,它始终指向特定的 Commit 对象。轻量级标签直接存储 Commit 对象的哈希值,文件路径在refs/tags/下;附注标签则是一个完整的对象,包含更多元数据,通过标签对象的指针指向对应的 Commit 对象 。
  1. git tag v1.0          # 轻量级标签
  2. git tag -a v1.0 -m "Release"  # 附注标签
复制代码
四、Git 的工作流程底层逻辑

明白 Git 的工作流程,有助于我们更好地掌握其底层原理。Git 的工作流程涉及工作区、暂存区和版本库三个区域。
4.1 工作区

工作区是我们日常编写和修改代码的地方,它是项目在本地磁盘上的现实目次。在工作区对文件举行的任何操作,如创建、修改、删除,都不会直接影响到版本库
4.2 暂存区

暂存区(也称为索引区)是一个临时区域,用于存放即将提交的文件修改。当我们使用git add下令时,工作区中被修改的文件内容会被计算哈希值,并存储为 Blob 对象,同时更新暂存区的相干信息,纪录文件的状态变革 。
4.3 版本库

版本库是 Git 存储全部对象(Blob、Tree、Commit、Tag)以及引用的地方,位于.git目次下。当我们实验git commit下令时,Git 会根据暂存区的内容创建一个新的 Tree 对象,纪录当前暂存区中文件的状态;然后创建一个新的 Commit 对象,指向新的 Tree 对象,并包含提交的元数据以及父 Commit 对象的指针,终极将新的 Commit 对象和相干对象存储到版本库中 。
五、总结

相识 Git 底层原理,在现实开发中有诸多利益。当遇到分支归并冲突、误删提交等题目时,基于对底层对象和引用的明白,我们能够更清晰地分析题目根源,通过git reflog检察引用日志,使用git reset、git cherry-pick等下令灵活地修复题目,本文通过对最基础的add,commit的下令的底层的讲解,入门git的底层原理

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

万万哇

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表