什么是Git引用和分支?

一. 引言

什么是Git引用和分支?比如我在 Github 上一个项目的 .git/refs目录下:

├─heads
│      dev
│      master
│
├─remotes
│  └─origin
│          master
│
└─tags

refs 目录下包含了 heads、remote、tags 三个子目录,每个子目录下都有对应的文件
打开 heads/master 文件,查看其内容:

$ cat heads/master
1b41db435c03fe80fa965dc77442261708deb16d

上述这段编码,其实就是 SHA-1 值,再来看看其类型和内容:

$ git cat-file -p 1b41d
tree 03073e441d5360400b758257647c2a0250ee38c7
parent 90157be126d9204779c63aaadf3a95f5fa207fc4
author haohuin <huins...@gmil.com> 1623935829 +0800
committer haohuin <huins...@gmil.com> 1623935829 +0800
系统介绍Readme

这个 SHA-1 值就指向 Git 仓库中的某个提交对象 ID。既然能用 SHA-1 值来区分不同的提交对象,为何要创建一个存放 SHA-1 值的文件呢?因为 SHA-1 值过于长,而且没有规律,如果利用简单的文件名来引用对原来的提交对象,就不用记住复杂且无规律的 SHA-1 值了。
因此在 Git 中,像这种只含有 SHA-1 值的文件,就是 Git 的引用(Reference)。而分支,就是一个指向某一系列提交之首的指针或引用。如下图所示:
 

image.png


下面就讲解一下 Git 中的引用和分支的具体内容

二. Git引用

在引言中提到过,Git 引用内部存储着 SHA-1 值,来跟踪和引用不同的 Git 对象,从类型上讲,可以分成 HEAD 引用,分支引用(branch),标签引用(tag)和远程引用(remote):

2.1. HEAD引用

在 .git根目录中,有一个 HEAD 文件,我们先来查看一下 HEAD 文件中的内容:

$ cat .git/HEAD
ref: refs/heads/master

发现 HEAD 中的内容指向了一个引用 refs.heads/master,当执行 git checkout dev,将当前版本切换至 dev 分支后,HEAD 文件内容会变成如下引用值:

$ git checkout dev
Switched to branch 'dev'$ cat .git/HEAD
ref: refs/heads/dev

此时 HEAD 指向的分支成了 dev,说明 HEAD 的内容就是指向当前 Git 仓库所在的分支。HEAD 文件通常是一个符号引用(symbolic reference),指向目前所在的分支或提交。 所谓符号引用,表示它是一个指向其他引用的指针。让我们首先来看看指向分支的 HEAD:

2.1.1 指向分支

如下图所示,是 HEAD 指向某个分支:
 

image.png


我们可 通过 git checkout <分支名>来使得 HEAD 在不同分支中进行切换。
此外有一种特殊情况,会导致 HEAD 中的内容直接为某个提交对象的 SHA-1 ID 值:

2.1.2 指向某个提交对象

当使用 git checkout检出某个非分支引用指向下的提交对象时:

//先查看所有的提交对象$ git log
commit 1b41db435c03fe80fa965dc77442261708deb16d (HEAD -> dev, origin/master, master)
Author: haohuin <huins...@gmil.com> 
Date:   Thu Jun 17 21:17:09 2021 +0800系统介绍Readmecommit 90157be126d9204779c63aaadf3a95f5fa207fc4
Author: haohuin <huins...@gmil.com>
Date:   Thu Jun 17 21:08:07 2021 +0800基本功能完成commit f7d98432d5bc8c1a67e4c4f75795544cb8a7f4d0
Author: haohuin <huins...@gmil.com>
Date:   Thu Jan 21 21:26:48 2021 +0800init repository//将HEAD指向最早的提交-init repository
$ git checkout f7d98432d5bc
Note: switching to 'f7d98432d5bc'.You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:git switch -c <new-branch-name>Or undo this operation with:git switch -Turn off this advice by setting config variable advice.detachedHead to falseHEAD is now at f7d9843 init repository

而后出现了一大段的描述,其实现在就处于"detached HEAD"(分离头指针)状态,我们再来看看此时 HEAD 中的内容:

$ cat .git/HEAD
f7d98432d5bc8c1a67e4c4f75795544cb8a7f4d0

此时 HEAD 指向了一个具体的提交 ID,而不是一个分支引用。
在这种情况下,如果再次进行提交操作,创建了一个新的提交,但是此时的 master 和 dev 分支引用都不会向前移动。HEAD 也不会指向这个新提交,那么因为没有引用指向该提交,Git 的垃圾回收机制可能最后会清理掉这个提交:
 

image.png


但是分离头指针的这个特性,也有助于创建临时分支的情景。
总结来说,HEAD 引用有以下作用:

  • 当 HEAD 指向当前所处的分支或提交,它表示正在工作的位置。当再执行 Git 操作时,比如提交,检出分支等时,Git 根据 HEAD 的位置确定在哪个分支上进行操作。
  • 当 HEAD 指向某一个具体的提交时,会进入分离头指针状态。在这种状态下,可以在历史提交上工作,创建新的提交,但不会更新任何分支。这在实验性工作、查看旧版本代码或创建临时分支时很有用。
  • 当 HEAD 执行分支时,可以使用 ^ 符号用于引用上一次提交。例如,HEAD^ 表示 HEAD 的父提交,HEAD^^ 表示 HEAD 的父提交的父提交,以此类推。这在查看提交历史、比较版本之间的差异等操作中很有用。
  • 当存在合并冲突时,HEAD 在解决冲突时起到重要作用。HEAD 指向当前分支的最新提交,同时也是合并操作的目标分支。可以通过编辑冲突文件并执行合适的操作,来解决冲突后进行提交。

2.2. 分支引用

在Git中,分支引用是指向特定提交(commit)的可变指针。它们用于跟踪各个分支在代码库中的位置,以便在不同的提交之间进行切换和管理。

2.2.1 本地分支

分支引用存储在 .git/refs/heads 目录下,每个分支引用对应该目录下的一个文件。比如在当前仓库下的 .git/refs/heads目录下有两个分支 dev 和 master,其内部存储的值如下:

$ cat .git/refs/heads/master
1b41db435c03fe80fa965dc77442261708deb16d
$ cat .git/refs/heads/dev
1b41db435c03fe80fa965dc77442261708deb16d
$ git cat-file -p 1b41db4
tree 03073e441d5360400b758257647c2a0250ee38c7
parent 90157be126d9204779c63aaadf3a95f5fa207fc4
author haohuin <huins...@gmil.com> 1623935829 +0800
committer haohuin <huins...@gmil.com> 1623935829 +0800系统介绍Readme

两个分支文件内部的内容就是指向某个提交对象,此处两个分支指向的提交对象一致。
分支引用通常是指向最新提交的指针。当在分支上进行提交时,分支引用会自动更新以指向新的提交。这样,Git就能够跟踪分支的进展和历史记录。
除了本地分支引用,还有远程分支引用。

2.2.2 远程分支

远程分支引用跟踪远程仓库中的分支。这些引用存储在 .git/refs/remotes/ 目录下。
如果你添加了一个远程版本库并对其执行过推送操作,Git 会记录下最近一次推送操作时每一个分支所对应的值,并保存 refs/remotes 目录下。在我的项目中有远程提交的仓库 orgin,可以通过 git remote showw 来看看当前远程仓库:

$ git remote show
origin
$ cat .git/refs/remotes/origin/master
1b41db435c03fe80fa965dc77442261708deb16d

此时远程仓库 origin中的分支 master对应的 SHA-1 值就是本地仓库中最新的提交对象。

远程引用和分支(位于 refs/heads 目录下的引用)之间最主要的区别在于,远程引用是只读的。 虽然可以 git checkout 到某个远程引用,但是 Git 并不会将 HEAD 引用指向该远程引用。因此,你永远不能通过 commit 命令来更新远程引用。 Git 将这些远程引用作为记录远程服务器上各分支最后已知位置状态的书签来管理。

在远程引用中,可能会涉及到引用规范的内容,具体可以看这篇文章Git - 引用规范

2.3. 标签引用

除了 HEAD 引用和分支引用,在 Git 对象中还有标签对象,从前面的深入剖析Git对象底层原理我们知道,标签对象有两种:

  • 轻量标签:只有一个固定的指向提交对象的引用值,类似于分支引用
  • 附注标签:会创建一个标签对象,其中记录一个引用来指向该标签对象

标签对象类似于分支引用,但与分支引用不同的是,标签对象是不可变的,一旦创建就不能更改。
标签对象通常用于指定软件版本、发布快照或重要里程碑。它们提供了一个有意义的名称来标识特定的提交或代码状态。
标签对象存储在 .git/refs/tags/ 目录下,每个标签对应该目录下的一个文件。例如,如果有一个名为 firstTag 的标签,对应的标签对象文件就是 .git/refs/tags/firstTag
在我的仓库中分别存储了两种标签,可以看到其对应的标签,以及其引用的对象:

$ find .git/refs/tags/
.git/refs/tags/
.git/refs/tags/firstTag
.git/refs/tags/secondTag//1.查看轻量标签,其内部引用值指向提交对象
$ cat .git/refs/tags/firstTag
2b2af66549827bd6a466fe43081f406c2a12900b$ git cat-file -p firstTag
tree 2503e9e0c4f774fc5ce298f4972f0e6d3a800d6f
parent 7b34a1e750918570ed610ee1f228e83b43a1192e
author haohuin <huins...@gmil.com> 1705458723 +0800
committer haohuin <huins...@gmil.com> 1705458723 +0800second commit//2.查看附注标签,其内部引用值指向标签对象
$ cat .git/refs/tags/secondTag
9cb2c0bd900b37a05f7c531fdd07cece35097045$ git cat-file -p secondTag
object 8a4678fae181c16c6f4ff0e6a618991128d86da2
type commit
tag secondTag
tagger haohuin <huins...@gmil.com> 1705480524 +0800secondTag

三. 总结

总体来说,引用机制让Git可以通过简单但唯一的ID来识别和追踪对象,管理项目版本以及支持分布式协作开发模式。Git中的引用主要包括

  1. HEAD引用,指向当前检出的分支或提交对象。HEAD管理 Git 当前操作所在的分支或提交状态。
  2. 分支引用,存储在.git/refs/heads目录下,每个分支对应一个引用文件。指向某个提交对象,跟踪分支历史记录和进度。本地分支和远程分支分别保存在不同目录下。
  3. 标签引用,存储在.git/refs/tags目录下,每个标签对应一个文件或对象。用于标记特定版本,不可变更。分支和标签都是引用的一种,但功能不同。分支指导开发顺序,标签标记具体版本。

技术前沿拓展

前端开发,你的认知不能仅局限于技术内,需要发散思维了解技术圈的前沿知识。细心的人会发现,开发内部工具的过程中,大量的页面、场景、组件等在不断重复,这种重复造轮子的工作,浪费工程师的大量时间。

介绍一款程序员都应该知道的软件JNPF快速开发平台,很多人都尝试用过它,它是功能的集大成者,任何信息化系统都可以基于它开发出来。

这是一个基于 Java Boot/.Net Core 构建的简单、跨平台快速开发框架。前后端封装了上千个常用类,方便扩展;集成了代码生成器,支持前后端业务代码生成,实现快速开发,提升工作效率;框架集成了表单、报表、图表、大屏等各种常用的 Demo 方便直接使用;后端框架支持 Vue2、Vue3。如果你有闲暇时间,可以做个知识拓展。

看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

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

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

相关文章

openCV制作九宫格图片

我想将任意九张图片按照九宫格排列方式合并成一张大图&#xff0c;使用openCV实现。 如果用画图工具来实现的话&#xff0c;需要事先准备一个600 X 600像素的画布。用openCV实现也是同理&#xff0c;准备一张600 X 600的图片。然后将图片划分成9份&#xff0c;每一份替换成小图…

《Ubuntu20.04环境下的ROS进阶学习0》

一、逛ROS应用商店 在上一专栏http://t.csdnimg.cn/oGlcu&#xff0c;我们了解了ROS的基本功能。这一专栏将会在此基础上做出进一步拓展学习。那么首先我们要学会下载并阅读别人的代码。常用的两个应用商店一个是ROS的官方应用商店ROS index&#xff0c;另一个就是我们熟知的gi…

11---数字温度 OR 湿度传感器电路设计

视频链接 数字温度or湿度传感器电路设计02_哔哩哔哩_bilibili 数字温度 OR 湿度传感器电路设计 1、温湿度传感器 DHT11 DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度-5%RH&#xff0c; 温度-2℃&#xff0c;量程湿度20-90%RH&#xff0c; 温度0~50℃。 D…

MySQL临时表创建出错(OS errno 13 - Permission denied)

一个客户向我抱怨&#xff1a;在MySQL查询小表没有问题&#xff0c;查询大表出错&#xff0c;下面是他发给我的出错的部分截屏&#xff08;客户的表名被我隐藏了&#xff09;。 这里的给出的信息已经比较明显了&#xff0c;是向/tmp目录中创建临时表失败&#xff08;临时表的路…

【嵌入式——QT】Splash与登录窗口

一般的大型应用程序在启动时会显示一个启动画面&#xff0c;即Splash窗口&#xff0c;Splash窗口是一个无边对话框&#xff0c;一般显示一个图片&#xff0c;展示软件信息&#xff0c;Splash窗口显示时&#xff0c;程序在后台做一些比较耗时的启动准备工作&#xff0c;Splash窗…

《腾讯音乐》24校招Java后端一面面经

1.手写LRU 2.项目拷打 3.Https客户端校验证书的细节&#xff1f; 4.对称加密和非对称加密的区别&#xff1f;你分别了解哪些算法&#xff1f; 5.在信息传输过程中&#xff0c;Https用的是对称加密还是非对称加密&#xff1f; 6.怎么防止下载的文件被劫持和篡改&#xff1f; 7.H…

linux进程间通信-信号量

Linux c/c之IPC进程间通信 Linux - 进程间通信之信号量

Websocket在Asp.net webApi(.net framework)上的应用

之前在写看板部分的web api的时候&#xff0c;都是通过Ajax在规定时间内轮询调用web api&#xff0c;这样简单省事&#xff0c;但是当看板多了&#xff08;并发量上来&#xff09;以后&#xff0c;比较消耗服务器的性能&#xff0c;所以最近研究了websocket&#xff0c;希望使用…

【机器学习】决策树系统 | 决策树基本原理,最优划分属性,剪枝处理

文章目录 1 基本原理2 最优划分属性选择2.1 信息增益选择最优属性方法2.2 信息增益率选择最优属性方法——C4.5决策树2.3 基尼指数选择最优属性——CART决策树 3 剪枝处理3.1 预剪枝3.2 后剪枝 决策树是一种常用的机器学习算法&#xff0c;它模拟了人类决策过程中的思考方式。想…

【CSS面试题】外边距折叠的原因和解决

参考文章 什么时候出现外边距塌陷 外边距塌陷&#xff0c;也叫外边距折叠&#xff0c;在普通文档流中&#xff0c;在垂直方向上的2个或多个相邻的块级元素&#xff08;父子或者兄弟&#xff09;外边距合并成一个外边距的现象&#xff0c;不过只有上下外边距才会有塌陷&#x…

OpenCV学习笔记 使用OpenCV进行人脸交换

一、简述 首先说换脸这件事情,已经可以算是有一丢丢古老的技术了,基于OpenCV进行人脸交换的好处在于简单,坏处在于无法复刻表情。如果想要比较完美的可以去找deepfakes相关技术,如果想要对脸部进行一些自定义操作,那么了解OpenCV换脸涉及到的技术点还是有价值的。 基于Ope…

每日一题——LeetCode1668.最大重复字符串

方法一 includes()repeat()秒了 使用repeat()将word重复i次&#xff0c;看是否包含于sequence中&#xff0c;将最大的i赋值给k var maxRepeating function(sequence, word) {let k0for(let i1;i*word.length<sequence.length;i){if(sequence.includes(word.repeat(i))){k…

Python从0到100(三):Python中的变量介绍

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

CleanMyMac X4.15具有哪些功能和特点?

CleanMyMac X具有许多其他功能和特点&#xff0c;以下是一些主要亮点&#xff1a; 系统清理&#xff1a;它能够深入扫描macOS系统&#xff0c;识别并清除各种垃圾文件&#xff0c;如缓存、日志、无用的语言文件等。这不仅有助于释放硬盘空间&#xff0c;还可以提高系统的整体性…

【硬件工程师面经整理27_其它】

文章目录 1 片选空间2 嵌入式系统的地址空间3 对x86架构有多少了解?4 存储中有哪几个重要的参数&#xff1f;5 提升代码效率和稳定性的方法 1 片选空间 片选空间&#xff08;Chip Select Space&#xff09;是指在嵌入式系统中&#xff0c;由多个设备共享的地址空间&#xff0…

基于51单片机超声波测距

目录 摘 要 2 ABSTRACT 3 目 录 4 1 绪论 1 1 概述 12 国内外发展现状 1 2 系统总体方案设计 21 设计要求 2 1&#xff09;可进行距离测量。 2 2&#xff09; 采用数码管显示距离数据。 2 3&#xff09; 可按键设置距离门限值 2 4&#xff09; 具有报警功能 22 方案选择 2 1 …

【C#语言入门】16. 委托详解

【C#语言入门】16. 委托详解 一、什么是委托 委托&#xff08;delegate&#xff09;是函数指针的“升级版”一切皆地址 变量&#xff08;数据&#xff09;是以某个地址为起点的一段内存中所储存的值函数&#xff08;算法&#xff09;是以某个地址为起点的一段内存中所存储的一…

Python开源项目周排行 2024年第5周

Python 趋势周报&#xff0c;按周浏览往期 GitHub,Gitee 等最热门的Python开源项目&#xff0c;入选的项目主要参考GitHub Trending,部分参考了Gitee和其他。排名不分先后&#xff0c;都是当周相对热门的项目。 入选公式&#xff1d;70%GitHub Trending20%Gitee10%其他 关注微…

分治算法相关

分治算法&#xff08;Divide and Conquer&#xff09; 是一种解决问题的算法思想&#xff0c;它将一个大问题分解成若干个规模较小的子问题&#xff0c;然后分别解决每个子问题&#xff0c;最后将子问题的解合并成原问题的解。 以下是分治算法的一些相关知识点&#xff1a; …

杠杆和保证金关系,很简单,众汇一个表格解决

很多投资者都能一眼就可以理清杠杆和保证金的关系&#xff0c;但是众汇外汇也看到很多交易届的新手&#xff0c;有时还浪费精力在杠杆和保证金的关系上&#xff0c;白白损失了许多盈利的机会&#xff0c;其实很简单&#xff0c;今天众汇就一个表格解决这个问题。 在使用表格之…