Git 的原理

本文详细介绍了Git的工作原理,包括版本库的构成、暂存区、分支管理和版本库管理。Git是一个分布式版本控制系统,通过对象数据库存储版本历史,使用SHA1算法确保文件内容唯一。此外,文章还讲解了提交、分支、标签以及版本库之间的交互,如fetch、pull、push等操作。最后,探讨了Git在开发流程中的应用,如选择性提交、版本回滚和分支管理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是 Git?

Git 是一个分布式的版本控制系统。他的工作原理类似于区块链,严格来说,他是一个对象数据库。

Git 通过版本库来管理数据(代码)。这里的版本库,指的是开发者、或者服务器中托管的项目文件夹。在后文中,亦用版本库指由一系列历史项目文件、当前项目文件组成的文件夹。

对于一个开发者来说,他电脑上的项目文件,就叫本地版本库。而其他开发者的项目文件(有可能一样),就叫远程版本库。一般的,虽然分布式版本控制系统中,各个版本库都是同等地位的。但是为了开发方便,一般都会有一个公认的服务器,维护一个“官方”版本库。当然,假若这个官方版本库丢失了,那么可以用任何一个开发者的版本库顶上。这个官方版本库,也叫项目版本库。

不过,一个开发者,为了调试的方便,都有多个本地版本库。其中一个作为主版本库。另外的几个,一般作为调试之用。这些调试的版本库,一般称为克隆版本库。

版本库是由什么构成的

我们知道,一个项目文件,肯定包含源代码、说明文档、日志等等。由 Git 维护的版本控制系统中,一个项目文件也叫版本库。并且,区分与一般的文件管理系统,版本库除了有当前项目文件外,还包含了历史的所有项目文件,也即项目文件的历史版本(以下简称历史版本)和当前版本(以下简称当前版本)。

当然,当前版本、历史版本,并不是通过直接存储里面的项目文件,而是将它们经过处理后,转换成哈希数值存储在一个对象数据库中。这个数据库,相当于文件管理系统管理项目时,所用到的日志。只不过,可以通过这个“日志”,将项目文件恢复到历史状态。我们后面也会叫这个**“日志”为对象数据库**。

这究竟是怎么做到的呢?我们将在下一节说明。目前的主要任务,还是了解一下什么是版本库吧。

不过,在此之前,必须说明的一点是,在诸多介绍和书籍中,也将这个日志数据库,称为版本库。晕了?没关系,大家只要记住,版本库有时候是指项目文件夹的“日志数据库”(对象数据库)、也可以指项目文件夹。

注意,这里的术语,除了“日志数据库” 是笔者为了方便提出的之外,其余术语都来自官方资料

版本库(项目文件夹)的构成

版本库由:版本库(对象数据库)、工作区、缓存区构成。

其中工作区存储了实质的文件、以及文件目录。对象数据库,则存储了版本库的历史信息(历史版本等)。当然,他们都有相同的根目录,就是我们的版本库(项目文件夹)啦。
在这里插入图片描述
这样可能有点抽象,让我们看一个实际的例子:
在这里插入图片描述
其中, .git 就是我们的版本库(对象数据库)。而 folder1、folder2、ReadMe.md 就是我们的工作区了。

咦?缓存区呢?怎么没画出来。

缓存区又叫 index、暂存区。工作区中所做的每一次修改,并不会实时地、同步地更新给版本库。而是需要开发者手动提交,将修改弄成一个版本,存到缓存区中。然后,缓存区再正式地,将该版本加上适当的注释,添加到版本库中。

为什么要多此一举?我们先在此打住。在后续章节,我们将会仔细涉及。

版本库(对象数据库)的结构

前面提到:

工作区中所做的每一次修改,并不会实时地、同步地更新给版本库。而是需要开发者手动提交,将修改弄成一个版本,存到缓存区中。然后,缓存区再正式地,将该版本加上适当的注释,添加到版本库中。

这里有一个重要的概念,提交。但我们创建一个项目、并首次添加一些项目文件时,就会形成工作区。然后,我们需要用 git init 命令,生成一个空的版本库。

如果我们要将工作区所做的修改,包括文件的增、删、改、差等记录添加到版本库中,就要用到 git add xx [ xx 可以是所有文件、或指定的某些文件、文件夹],将 xx 作为一个版本,上传到缓冲区。然后,再用 git commit -m '注释' 将版本以及相应的注释,提交到版本库中。

一般的,我们修改了工作区,都必须以版本的形式,提交给数据库管理。

当然,版本不是工作区的简单复制。而是将工作区的文件、文件目录进行处理后,以哈希数值的形式,追加给版本库。

至此,大家应该能够理解版本库的构成了。版本库是由一系列版本构成的、以哈希值为内容的对象数据库
在这里插入图片描述
图中,每一个节点就是一个版本。每一个节点,是由工作区(历史工作区,若版本不是最新版本),处理成哈希散列构成的。当然,每一个版本,都是一次提交。因此,有时候也称版本为提交

版本库就是由提交构成的。这些提交,可能是基于上一次提交的提交,因此具有某些序列关系。

如何查看版本库的所有提交呢?可以用 git log [--oneline] \[--graph] [-n number] 实现。

提交的组成

我们重复了三遍,提交由工作区(历史工作区,若版本不是最新版本),处理成哈希散列构成的。具体怎么做呢?

对于当前提交对应的工作区的所有文件、目录(文件夹),我们给它们取个别名叫 blob、tree:

  • 对每一个 blob,我们将其内容根据 SHA1 算法,计算出一个 40 位的哈希值,用来代替其原始内容,存放在版本中。
  • 对每一个 tree&
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhuo木鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值