Git 浅入浅出

news2024/11/26 22:25:30

前提

最近和同事分模块联合开发代码,自然而然就要用到 Git 管理代码;借此机会,对 Git 进行简单介绍。

Git 的特征

文件系统
我们都知道 Git 是个版本控制系统,但是如果你深入了解其原理,就不难发现它更像一个文件管理系统,如果你使用过其他版本控制器,不难发现它们的思路非常符合“版本控制”的逻辑,它们记录的是一个初始文件,以及后续对该文件的历次修改内容,如下:
图片
而对于 GIT,则是把你每次的“提交”当作一次相机的“快门”,GIT 会为你把当时的全部文件内容都做一个快照,然后进行存储,这一系列的快照,每一个快照展开都是完整的文件系统。当然,为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。
图片
分布式
我们可以把上次的图继续拿来使用,GIT 的核心工作都是在本地完成的,即其主要工作都聚焦在工作区到本地仓库,这意味着,即使我们离线了,我们仍然能完成提交操作,GIT 仍然能忠实的记录下我们的操作记录,而不像其他版本控制器,断网后版本控制功能就失效了。
图片

GIT 的术语

在接触 GIT 的时候,我们难免会接触到一些术语或概念,我们先对术语做个解释,如果你看了某些解释,觉得一头雾水,先别着急,我们在下面会慢慢解释。
区域术语
GIT 一共分为四个区域,对于开发者来说,由远到近依次为:远程仓库、本地仓库、暂存区和工作区。

  • 远程仓库:可以是 GitHub、GitLab,也可以是你自己的私有服务器,包含项目所有的版本控制信息和文件历史记录。
  • 本地仓库:你电脑上的存储库,它包含项目所有的版本控制信息和文件历史记录。
  • 暂存区:也称为索引(Index),用于存储下一次提交时要包含哪些修改或变更。
  • 工作区:指项目的实际文件夹,即我们日常编辑的文件夹。

我们之前讲了三个部分,唯独没有讲暂存区。实际上,我们的代码不能直接从工作区就到仓库去,本地仓库只接收暂存区提供的内容,所以我们的任何新增、修改实际上都要先加入到暂存区。
图片
但是为什么这块暂存区存在感不强呢?主要是因为我们现在的各种工具在自动维护,比如我们添加文件时,IDEA 会自动弹窗,当我们使用 Tortoisegit 时,提交时会让我们勾选文件,这些都让我们免于手动往暂存区进行手动添加,自然其存在感就稍弱了。
图片
名词术语

  • 提交对象

我们每次把暂存区的内容放入本地仓库,称为一次提交,产生一个提交对象(也叫“提交点” 或 “提交”)。
除了手动提交,合并操作也会产生提交点,提交点包含了前一个提交点位置、文件变更信息、变更人、变更时间等所有信息,每个提交点都有自己的 SHA-1 哈希值作为唯一标志,一般在图中,用一个圈表示。因为提交点(除了首次提交)都会包含上一个提交点的地址,所以在实例图里一般呈链表状,如下图,就展示了三个提交点。
图片

  • 分支

定义:一个指向某个提交对象的指针,表示一个代码的分支。可以有多个分支,并行开发不同的功能或版本。

对于分支这个概念,在讲解之前,如果你看过其他的教程,可能会经常看到类似下面的图:
图片
这样的话,你会认为这里有两个分支,一个是由 C D E 构成,一个是 F G 构成。的确,这里是有两个分支不假,但这张图更具体的样子应该是这样子:
图片
分支并不是树枝,图中真正的分支,其实只是两个指针,如图,分支 iss94 指向提交点 G,分支 master 指向提交点 E,理解了这个概念,你才能明白为什么 Git 鼓励大家,遇事不决就建立各种分支。在其他版本控制器中,拉个分支可能意味着所有的代码都要复制一遍,而在 GIT 中,仅仅是建立一个指针。

聪明的你可能想到了一个问题,建分支=建指针,那岂不是当我建分支的时候,会产生两个指针,指着同一个节点?此时,如果我再次提交内容,岂不是乱了套?这个节点会算在哪个分支上?这时候就要用到另一个概念 HEAD。

  • HEAD

定义:HEAD 是一个特殊的指针,它指向当前所在的分支或提交。一般情况下,HEAD指向当前所在分支的最新提交。

没错,HEAD 也是个指针,而且指向分支,如果你没有忘记分支也是个指针的话,那你应该能想象出下面的图例:
图片
这代表着 HEAD 指向了 master 分支,我们把前面分支的知识结合起来,现在如果我们想建立个名叫 iss95 的分支,图就会变成这样子:
图片
如果此时我们再进行一次提交,会变成什么样呢?
图片
所以,你应该明白 HEAD 的作用了,它代表着你下次提交的位置,此处它指向 master,所以我们的提交是提交至分支 master 上的。提交后,master 指针自动移到 C 的位置。而 iss95 则没有任何变化,还是指向 B。

严谨的小伙伴可能注意到我们定义中说了一句一般情况下,HEAD 指向当前所在分支的最新提交。那 HEAD 能指向历史提交吗?

答案是肯定的,我们可以使用 git checkout <commit> 命令将 HEAD 移动到某个历史提交点,如下图:
图片

  • 标签(TAG)

定义:在 Git 中,Tag 是一种重要的版本控制工具,它们是一些永久性的指针,指向某个特定的提交(commit),常用于代码发布、版本管理以及历史记录的标记等操作。

简而言之,标签也是一个指针,只是这个指针不像分支或 HEAD 一样,它是不会移动的,我们可以看到 JDK 源码中就有大量的标签,用以标记节点。
图片
动作术语

  • 添加(Add):将工作目录的文件加入暂存区,可以只选择部分文件进行添加。

  • 提交(Commit):将暂存区的内容放入本地仓库,每个提交都有唯一的 ID。

  • 合并(Merge):将两个或多个分支的修改合并到一起。

  • 拉取(Pull):将远程仓库的修改拉取到本地仓库,并更新工作区。

  • 推送(Push):将本地仓库的修改推送到远程仓库。

  • 检出(Checkout):切换某个分支,并同时切换工作目录。

如果前面你都学会了,相信这几个动作,你应该能理解,它们之前能汇聚成下面这张关系图:
图片
当然,这些命令实际上并不仅仅这么简单,比如 Checkout 不仅可以切换分支,还可以跟文件名,以 git checkout <file-name> 来还原文件。

Git 存储模型

GIT 数据库
前面我们三番五次的把 GIT 说成更像文件系统,这是很合理的。甚至可以说 GIT 是一个数据库,其实它的核心确实就是一个键值对数据库,你可以向 Git 仓库中插入任意类型的内容,它会返回一个唯一的键,通过该键可以在任意时刻再次取回该内容:

$ echo ‘test content’ | git hash-object -w --stdin
d670460b4b4aece5915caf5c68d12f560a9fe3e4

如上,我们把标准输入内容“test content”存储进 GIT,它就会返回给我们一个40字符的 SHA-1 哈希值,我们可以用这个值,重新获取存进去的内容:

$ git cat-file -p d670460b4b4aece5915caf5c68d12f560a9fe3e4
test content

但注意,使用这种方式存入文件,返回的只有文件内容,等于说文件名我们丢失了,而文件名的遗失对于文件系统来说,是非常不合理的。所以我们还需要树。
树对象
比方说我们有一个简单的目录,目录下有两个文件,README 以及 Rakefile,并且还有个子目录 lib,lib 里有个文件 simplegit.rb。那么当我们把这个目录及其所有文件纳入 GIT 管理时,其形态是这样的:
图片
它会把我们的文件存储成 blob 对象,目录变成 tree 对象。tree 对象可以存文件信息,blob 对象存文件内容,而且 tree 对象还能下辖另一个 tree 对象,这就和我们目录下还有子目录是一样的。如此一来,我们就可以把我们想存放的目录及其文件,以一棵树的形式完整的存入 GIT 中了。存是存进去了,但这仅仅是一次保存,存进去最多说 GIT 保存了我这个目录,那么它的版本控制又体现在哪呢?
提交对象
我们上面说了整个目录能变成一个 Tree 对象存入 GIT,它是什么时候情况下会存呢?其实就是 GIT 执行提交命令的时候,当我们提交时,GIT 会把我们整个工作目录的所有文件汇聚成一个 Tree,并且把这个 Tree 的引用放进一个提交对象中进行存储。
图片
也就是说,如上图,每一个圈(提交对象)不仅有本次提交人、提交时间等信息、而且还指向着一个 Tree,所以提交对象实际上就是一个快照。
图片
如上图,三次提交实际上构成了一个不断往上摞的切面,为啥说是切面,是因为每一个切面都包含着一棵树,也就是当时整个目录的内容。因此信息量其实是很多的。当然,提交对象、和树对象或者文件对象一样,都会存进 GIT,GIT 也会返回一个40长度的 SHA-1 哈希值。

这样当我们查询提交历史时,查询到的就是所有过往的提交对象的信息,如果我们确定某个提交对象后,我们就能通过该提交对象的 SHA-1 哈希值能找回当时所有的文件。

$ git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the version number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

Tree 对象不是压缩包,它只是存储着当时那些文件对象的引用。另外,提交时形成的 Tree 并不是把所有的文件全部又做一遍保存,然后把引用放进 Tree,而是只保存改动或新增的文件,那些没有改动过的文件已经存过了,不会再存,所以不用过分担心空间问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1342659.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

区间DP详解,思路分析,OJ详解

文章目录 前言问题引入暴力枚举自下而上状态设计状态转移方程 区间DP的分析状态设计状态转移时间复杂度翻译成递推 OJ详解P1880 [NOI1995] 石子合并记忆化搜索版本递推版本 HDU Dire WolfMultiplication PuzzlePolygon 总结 前言 区间dp属于动态规划中一类比较好理解的问题&…

概率论相关题型

文章目录 概率论的基本概念放杯子问题条件概率与重要公式的结合独立的运用 随机变量以及分布离散随机变量的分布函数特点连续随机变量的分布函数在某一点的值为0正态分布标准化随机变量函数的分布 多维随机变量以及分布条件概率max 与 min 函数的相关计算二维随机变量二维随机变…

超级详细的YOLOV8教程

超级详细的YOLOV8教程 YOLOV8介绍1. 数据标记1.1 第一种为在网站上下载&#xff0c;1.2 第二种为在CVAT上自定义数据 2. 制作数据集3. 部署YOLOV8的代码3.1 远程部署3.1.1 项目下载3.1.2 修改代码3.1.2.1 训练模型3.1.2.1 验证模型 3.2 本地部署3.2.1 YOLOV8项目部署3.2.2 cuda…

2023总结与展望--Empirefree

今年一篇博客都没写过了&#xff0c;好像完全在忙在工作和生活上面了&#xff0c;珍惜自我&#xff0c;保持热情&#xff0c;2024对我好点 文章目录 &#x1f525;1. 年终总结1.1.学习工作计划1.2. 生活计划1.3 个人总结 &#x1f525;2. 未来展望 &#x1f525;1. 年终总结 1…

基于Java学生成绩管理系统设计与实现(源码+部署文档+报告)

博主介绍&#xff1a; ✌至今服务客户已经1000、专注于Java技术领域、项目定制、技术答疑、开发工具、毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精彩专栏 推荐订阅 &#x1f447;&#x1f3fb; 不然下次找不到 Java项目精品实…

两阶段提交协议

数据的强一致性 要么都修改 要么就都不修改。 不同的实体和过程 领导者和参与者、表决阶段和提交阶段 过程 一个不同意 提交就终止 存在的问题和解决的方案 如果一个领导者或者参与者的状态机中有阻塞状态&#xff0c;那么系统必须等他完成才能执行&#xff0c;这样就会…

【并发编程篇】线程安全问题_—_ConcurrentHashMap

文章目录 &#x1f354;情景引入&#x1f339;报错了&#xff0c;解决方案 &#x1f354;情景引入 我们运行下面的代码 package org.example.unsafe;import java.util.HashMap; import java.util.Map; import java.util.UUID;public class MapTest {public static void main(…

SpringBoot单点登录认证系统MaxKey(附开源项目地址)

1 项目介绍 MaxKey 单点登录认证系统&#xff0c;谐音马克思的钥匙寓意是最大钥匙&#xff0c;支持 OAuth 2.x/OpenID Connect、SAML 2.0、JWT、CAS、SCIM 等标准协议&#xff0c;提供简单、标准、安全和开放的用户身份管理(IDM)、身份认证(AM)、单点登录(SSO)、RBAC 权限管理…

如何把握品牌新五感,打造小红书品牌

随着社会经济的发展&#xff0c;市场的进步&#xff0c;以及人们思维方式的改变。年轻人面对市场&#xff0c;面对营销&#xff0c;关注点也在发生着改变。那什么是小红书品牌新五感&#xff0c;如何把握品牌新五感&#xff0c;打造小红书品牌&#xff01; 一、品牌五感是什么 …

查找dll的开放函数以及dll的依赖dll

1.进入一个vs的cmd窗口 2.dumpbin /exports XXX.dll&#xff0c;分析 XXX.dll 中有哪些函数。 例如查询: C:\Users\levi0\Desktop\testPro\NewCSDll\NewCSDll\bin\x64\Debug\GBRAnalyze.dll 3. dumpbin /dependents 文件名&#xff08;带路径&#xff09;命令&#xff0c;回车&…

servlet+jdbc实现用户注册功能

一、需求 在Servlet中可以使用JDBC技术访问数据库&#xff0c;常见功能如下&#xff1a; 查询DB数据&#xff0c;然后生成显示页面&#xff0c;例如&#xff1a;列表显示功能。接收请求参数&#xff0c;然后对DB操作&#xff0c;例如&#xff1a;注册、登录、修改密码等功能。…

Linux中磁盘管理与文件系统

目录 一.磁盘基础&#xff1a; 1.磁盘的结构&#xff1a; 2.硬盘的数据结构&#xff1a; 3.硬盘存储容量 &#xff1a; 4.硬盘接口类型&#xff1a; 二.MBR与磁盘分区&#xff1a; 1.MBR的概念&#xff1a; 2.硬盘的分区&#xff1a; 为什么分区&#xff1a; 2.表示&am…

【PHP】B/S手术室麻醉信息管理系统源码

手术麻醉临床信息系统全面覆盖从患者入院&#xff0c;经过术前、术中、术后&#xff0c;直至出院的全过程。通过与相关医疗仪器的设备集成&#xff0c;不但可以轻松集成手术室传统监护设备如监护仪、麻醉机、呼吸机&#xff0c;也能与血气分析仪等设备对接&#xff0c;快速获取…

java并发编程十三 线程池

文章目录 线程池自定义线程池ThreadPoolExecutor提交任务关闭线程池任务调度线程池正确处理执行任务异常 线程池 自定义线程池 步骤1&#xff1a;自定义拒绝策略接口 FunctionalInterface // 拒绝策略 public interface RejectPolicy<T> {void reject(BlockingQueue&l…

LeetCode---120双周赛

题目列表 2970. 统计移除递增子数组的数目 I 2971. 找到最大周长的多边形 2972. 统计移除递增子数组的数目 II 2973. 树中每个节点放置的金币数目 一、统计移除递增子数组的数目I 这题的数据范围不高&#xff0c;可以直接暴力&#xff0c;后面的第三题和它一样&#xff0c…

程序员面试笔试通关宝典系列丛书(由清华大学出版社出版)

程序员面试笔试通关宝典系列——编程职场成功的必备秘籍 由清华大学出版社出版的专为编程爱好者和职业开发者打造的“程序员面试笔试通关宝典”系列丛书。该系列包含五本专业指南&#xff0c;覆盖数据库、Java、前端、通用编程和Python五个领域。 这些书籍深度解析各领域的核…

面试题:MySQL 自增主键一定是连续的吗?

文章目录 测试环境&#xff1a;一、自增值的属性特征&#xff1a;1. 自增主键值是存储在哪的&#xff1f;2. 自增主键值的修改机制&#xff1f; 二、新增语句自增主键是如何变化的&#xff1a;三、自增主键值不连续情况&#xff1a;&#xff08;唯一主键冲突&#xff09;四、自…

AIGC开发:调用openai的API接口

简介 开始进行最简单的使用&#xff1a;通过API调用openai的模型能力 OpenAI的能力如下图&#xff1a; 文本生成模型 OpenAI 的文本生成模型&#xff08;通常称为生成式预训练 Transformer 或大型语言模型&#xff09;经过训练可以理解自然语言、代码和图像。这些模型提供文…

扫雷(c语言)

先开一个test.c文件用来游戏的逻辑测试&#xff0c;在分别开一个game.c文件和game.h头文件用来实现游戏的逻辑 主要步骤&#xff1a; 游戏规则&#xff1a; 输入1&#xff08;0&#xff09;开始&#xff08;结束&#xff09;游戏&#xff0c;输入一个坐标&#xff0c;如果该坐…

新药(化药)注册申报资料都包含哪些?

新药的注册申报是新药上市前的重要步骤,其流程可以简单概括为①前期准备→②申报材料准备→③递交注册申请→④审评和审批→⑤监管和跟踪。本文将着重介绍新药(化药)注册申报的一般流程和主要环节(附流程图)。(关于新药注册申报成功率和耗费时间问题写到最后) ①前期准备 在开…