Git 浅入浅出

前提

最近和同事分模块联合开发代码,自然而然就要用到 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 -0700changed the version numbercommit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700removed unnecessary testcommit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gee-mail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700first commit

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

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

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

相关文章

快速解决找不到msvcp120.dll的五个方法,dll文件修复方法

本文将详细介绍msvcr120.dll文件的相关知识&#xff0c;并提供五种解决msvcr120.dll缺失的方法。 一、msvcr120.dll是什么文件和msvcr120.dll的作用是什么介绍 msvcr120.dll是Microsoft Visual C Redistributable Package的一部分&#xff0c;它是运行许多基于Windows操作系统…

【js自定义鼠标样式】【js自定义鼠标动画】

文章目录 前言一、效果图二、实现步骤1. 去除原有鼠标样式2. 自定义鼠标样式3. 使用 总结 前言 自定义鼠标形状&#xff0c;自定义鼠标的动画&#xff0c;可以让我们的页面更加有设计感。 当前需求&#xff1a;吧鼠标自定义成一个正方形&#xff0c;鼠标的效果有&#xff1a;和…

sysbench

一、sysbench介绍 1、sysbench简介 sysBench是一个模块化的、跨平台、多线程基准测试工具&#xff0c;主要用于评估测试各种不同系统参数下的数据库负载情况。sysbench提供如下测试&#xff1a; &#xff08;1&#xff09;CPU性能 &#xff08;2&#xff09;磁盘IO性能 &…

SourceTree的安装和使用

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、安装&#xff1a;二、使用步骤1.获取地址2.放入sourceTree 3.点击推送 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 简单讲解一…

Vue - 实现文件导出文件保存下载

1 文件导出&#xff1a;使用XLSX插件 需求背景&#xff1a;纯前端导出&#xff0c;如 在前端页面勾选部分表格数据&#xff0c;点击"导出"按钮导出Excel文件。 实现思路&#xff1a; 1.通过XLSX插件的 XLSX.utils.book_new()方法&#xff0c;创建excel工作蒲对象wb…

既然前端工程师可以进腾讯字节阿里等大厂,为什么要高薪进小公司?

前言 前不久后台有一个粉丝给我留言&#xff1a;为什么很多人参加校招的时候&#xff0c;宁愿低薪也要进大厂&#xff0c;而不选择更高薪的小公司呢&#xff1f; &#xff08;文末有惊喜&#xff01;文末有惊喜&#xff01;&#xff09; 我想了一下&#xff0c;大概是有3个原因…

6130 树的最长路

思路&#xff1a;树的最长路问题可以通过两次 DFS 求解&#xff0c;具体思路如下&#xff1a; 1.第一次 DFS 求树的直径 以任意一个点为起点进行深度优先遍历&#xff08;DFS&#xff09;&#xff0c;找到与该点距离最远的点 u 。 以 u 为起点进行 DFS &#xff0c;找到与 u 距…

win10系统gpu本地部署chatglm3-6b,从0开始安装

开源地址&#xff1a; GitHub - THUDM/ChatGLM3: ChatGLM3 series: Open Bilingual Chat LLMs | 开源双语对话语言模型 前言&#xff1a;ChatGLM2与ChatGLM3区别 ChatGLM2与ChatGLM3模型架构是完全一致的&#xff0c;ChatGLM与后继者结构不同。可见ChatGLM3相对于ChatGLM2没…

LabVIEW在电机噪声与振动探测的应用

LabVIEW在电机噪声与振动探测的应用 硬件部分是电机噪声和振动测试分析系统的基础&#xff0c;主要由三大核心组件构成&#xff1a;高灵敏度振动传感器、先进的信号调理电路和高性能数据采集卡。这些设备协同工作&#xff0c;确保了从电机捕获的噪声和振动信号的准确性和可靠性…

盲盒电商:重塑消费者行为与市场格局

一、什么是盲盒电商&#xff1f; 盲盒电商是一种新型的电子商务模式&#xff0c;它通过将商品隐藏在盲盒中&#xff0c;让消费者在购买时无法知道具体商品&#xff0c;只能通过猜测和期待来体验购物的乐趣。这种模式在年轻人中非常受欢迎&#xff0c;因为它提供了一种全新的购…

labuladong日常刷题-递归魔法 | LeetCode 206反转链表 92反转链表-ii

递归魔法 LeetCode 206 反转链表 2023.12.26 题目链接labuladong讲解[链接] ListNode* reverseList(ListNode* head) {//递归退出条件if(head NULL || head->next NULL)return head;//递归ListNode* last reverseList(head->next);//处理head->next->next …

电脑msvcr120.dll丢失怎样修复,一分钟教会你修复方法

在计算机使用过程中&#xff0c;我们可能会遇到各种问题&#xff0c;其中之一就是“msvcr120.dll丢失”的错误提示。这个错误通常发生在运行某些程序时&#xff0c;由于系统缺少了msvcr120.dll文件&#xff0c;导致程序无法正常运行。那么&#xff0c;什么是msvcr120.dll文件呢…

深入浅出理解转置卷积Conv2DTranspose

温故而知新&#xff0c;可以为师矣&#xff01; 一、参考资料 论文&#xff1a;A guide to convolution arithmetic for deep learning github源码&#xff1a;Convolution arithmetic bilibili视频&#xff1a;转置卷积&#xff08;transposed convolution&#xff09; 转置…

【C++】引用详解

前言 在学习C语言时&#xff0c;我们通常会遇到两个数交换的问题&#xff0c;为了实现这一功能&#xff0c;我们会编写一个经典的Swap函数&#xff0c;如下所示&#xff1a; void Swap(int *a, int *b) {int tmp *a;*a *b;*b tmp; } 然而&#xff0c;这个Swap函数看起来可…

智能监控平台/视频共享融合系统EasyCVR点击通道后页面分页不显示是什么原因?如何解决?

TSINGSEE青犀视频监控汇聚平台EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力&…

leetcode 75. 颜色分类(medium)(优质解法)

链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 代码&#xff1a; class Solution {public void sortColors(int[] nums) {int left-1,rightnums.length,i0;while(i<right){if(nums[i]0){left;swap(nums,left,i);i;}else if(nums…

LLaVA-v1.5-7B:实现先进多模态学习的开源AI

引言 LLaVA-v1.5-7B是一个开源大型多模态模型&#xff08;LMM&#xff09;&#xff0c;它通过结合视觉指令调整&#xff08;Visual Instruction Tuning&#xff09;技术&#xff0c;展示了在多模态理解和生成任务上的卓越性能。该模型特别注重简洁性和数据效率&#xff0c;利用…

一篇文章深入认识微服务SpringCloud和Dubbo的区别

1、SpringCloud是什么 SpringCloud, 基于SpringBoot提供了一套微服务解决方案&#xff0c;包括服务注册与发现&#xff0c;配置中心&#xff0c;全链路监控&#xff0c;服务网关&#xff0c;负载均衡&#xff0c;熔断器等组件&#xff0c;除了基于NetFlix的开源组件做高度抽象…

18B20受到LED灯的干扰处理方法

鱼缸使用了18B20测温&#xff0c;采用PWM控制加热棒加热占空比的方法控制鱼缸温度&#xff0c;使用了最简单的温度差调整PWM宽度的方法&#xff0c;温度差越大PWM占空比越大&#xff0c;从而产生更多的加热时间&#xff0c;当温度接近设定值的时候&#xff0c;PWM逐步缩小&…

limit查询报错问题

分页时候 limit 后面的公式是 (pageNum-1)*pageSize,pageSize 但是在数据库查询时候 当然在.XML中也不能像下面这么写,如果要计算 在业务层或者控制层计算好再传值进来