Git 分支本质及与 commit、HEAD、tag 之间的关系

news/2024/9/28 1:30:54

基于:

Git - Git 是什么?

Git - 分支简介

Git - 打标签

快照

在介绍 Git 分支前,需要知道什么是 commit 对象,介绍 commit 对象前,需要先了解 Git 保存数据的方式。Git 直接记录快照,而非差异比较。

从概念上来说,其它大部分版本控制系统(包括 Subversion 和近似工具)以文件变更列表的方式存储信息,这类系统将它们存储的信息看作是一组基本文件和每个文件随时间逐步累积的差异(它们通常称作基于差异的版本控制)。

存储每个文件与初始版本的差异
存储每个文件与初始版本的差异。

而在 Git 中,每当你提交更新或保存项目状态时,它基本上就会对当时的全部文件创建一个快照。为了效率,如果文件没有修改,Git 不再重新存储该文件,而是只保留一个链接指向之前存储的文件。Git 对待数据更像是一个快照流

存储项目随时间改变的快照
Git 存储项目随时间改变的快照。

这是 Git 与几乎所有其它版本控制系统的重要区别。

提交对象

在进行提交操作时,Git 会保存一个提交对象(commit object)。提交对象会包含一个指向快照的指针。该提交对象还包含了作者的姓名和邮箱、提交时输入的信息以及指向它的父对象的指针。首次提交产生的提交对象没有父对象,普通提交操作产生的提交对象有一个父对象,而由多个分支合并产生的提交对象有多个父对象。

分支本质

Git 的分支,其实本质上仅仅是指向提交对象的可变指针。Git 的默认分支名字是 master。在多次提交操作之后,你其实已经有一个指向最后那个提交对象的 master 分支。 master 分支会在每次提交时自动向前移动。

另:Git 的 master 分支并不是一个特殊分支。它就跟其它分支完全没有区别。之所以几乎每一个仓库都有 master 分支,是因为 git init 命令默认创建它,并且大多数人都懒得去改动它。

分支及其提交历史
分支及其提交历史。

分支创建

Git 创建新分支其实只是为你创建了一个可以移动的新的指针。比如,创建一个 testing 分支,你需要使用 git branch 命令:

$ git branch testing

这会在当前所在的提交对象上创建一个指针。

两个指向相同提交历史的分支
两个指向相同提交历史的分支。

Git 是怎么知道当前在哪一个分支上呢?它有一个名为 HEAD 的特殊指针,指向当前所在的本地分支(可以将 HEAD 想象为当前分支的别名)。前面创建了testing分支,但当前仍然在 master 分支上。因为 git branch 命令仅仅创建一个新分支,并不会自动切换到新分支中去。

HEAD 指向当前所在的分支
HEAD 指向当前所在的分支。

分支切换

要切换到一个已存在的分支,你需要使用 git checkout 命令。我们现在切换到新创建的 testing 分支去:

$ git checkout testing

这样 HEAD 就指向 testing 分支了。

HEAD 指向当前所在的分支
HEAD 指向当前所在的分支。

多分支开发

现在提交一次:

$ vim test.rb
$ git commit -a -m 'made a change'
HEAD 分支随着提交操作自动向前移动
HEAD 分支随着提交操作自动向前移动。

如图所示,你的 testing 分支向前移动了,但是 master 分支却没有,它仍然指向运行 git checkout 时所指的对象。现在我们切换回 master 分支:

$ git checkout master
检出时 HEAD 随之移动
检出时 HEAD 随之移动。

这条命令做了两件事。一是使 HEAD 指回 master 分支,二是将工作目录恢复成 master 分支所指向的快照内容。也就是说,你现在做修改的话,项目将始于一个较旧的版本。本质上来讲,这就是忽略 testing 分支所做的修改,以便于向另一个方向进行开发。

我们不妨再稍微做些修改并提交:

$ vim test.rb
$ git commit -a -m 'made other changes'

现在,这个项目的提交历史已经产生了分叉。上述两次改动针对的是不同分支:你可以在不同分支间不断地来回切换和工作,并在时机成熟时将它们合并起来。

项目分叉历史
项目分叉历史。

标签

在上面介绍分支本质的图中,包含了一个v1.0的标签,看上去和master差不多。

Git 支持两种标签:轻量标签(lightweight)与附注标签(annotated)。

  • 轻量标签很像一个不会改变的分支——它只是某个特定提交的引用。

  • 而附注标签是存储在 Git 数据库中的一个完整对象,其中包含打标签者的名字、电子邮件地址、日期时间,此外还有一个标签信息,所以,它像是一个存档起来的 commit 副本。

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

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

相关文章

k8s 分布式存储平台 -- Longhorn

目录一、什么是 Longhorn二、架构设计1、工作原理2、工作流程3、基于微服务设计的优势三、安装1、安装要求2、使用 Longhorn 命令行工具(验证方式一)3、使用环境检查脚本(验证方式之二)3.1、安装 jq3.2、运行脚本4、安装 open-iscsi4.1、SUSE 和 openSUSE4.2、Debian 和 Ub…

全网最适合入门的面向对象编程教程:53 Python 字符串与序列化-字符串与字符编码

在 Python 中,字符串是文本的表示,默认使用 Unicode 编码,这允许你处理各种字符集,字符编码是将字符转换为字节的规则,常见的编码包括UTF-8、UTF-16和ASCII。全网最适合入门的面向对象编程教程:53 Python 字符串与序列化-字符串与字符编码摘要: 在 Python 中,字符串是文…

【基础岛第3关】浦语提示词工程实践

[to2024-09-25 18:32:11 星期三c] 案例描述 0、前期准备 创建开发机 0.1 环境配置创建虚拟环境并激活创建虚拟环境conda create -n langgpt python=3.10 -y conda activate langgpt 2. 安装必要的库 # 安装一些必要的库 conda install pytorch==2.1.2 torchvision==0.16.2 torc…

9月27日swing知识点

swing是一系列图形用户界面的控件的集合 Swing中GUI类分为三大类: 容器类 JFrame、JPanel、JScrollPane UI组件类 JLabel、JTextField、JTextArea、JButton JCheckBox、JRadioButton、JComboBox 帮助类 Color、Font、Dimension 这三者的依存关系为组件必须依存在顶层容器中,组…

软件工程结对作业

这个作业属于哪个课程 软件工程这个作业要求在哪里 结对作业要求这个作业的目标 设计一个软件的方案原型学号 102202109(我)012202239(朱佳杰)《构建之法》第三章与第八章读后感 第三章:软件工程师的成长 1.1 个人能力的衡量与发展 在《构建之法》第三章中,作者详细阐述了…

油猴脚本使用指南

油猴插件介绍 官方介绍:篡改猴 (Tampermonkey) 是拥有 超过 1000 万用户 的最流行的浏览器扩展之一。 它适用于 Chrome、Microsoft Edge、Safari、Opera Next 和 Firefox。 有些人也会把篡改猴(Tampermonkey)称作油猴(Greasemonkey),尽管后者只是一款仅适用于 Firefox 浏览器…

一些常用的技巧分享

0. 前言 最近很多uu们过来问鼠鼠一些 c语言/python 的问题,遂决定开一个答疑帖,方便大家学习交流。但是呢既然开了帖,也就不只讲有疑问的地方,顺便把常见的一些问题都给大家过一遍。又考虑到很多uu跟鼠鼠一样是电脑小白,也顺带分享一些电子产品、生活小知识。 鼠鼠水平有限…