git中的head到底是怎么工作的,十分钟就够了

2024-08-31 16:04

本文主要是介绍git中的head到底是怎么工作的,十分钟就够了,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

git中的head到底是怎么工作的,十分钟就够了

  • 背景
  • HEAD 实际上是一些不同的东西
  • 文件 .git/HEAD
  • HEAD如同git show HEAD
  • 下一步:所有输出格式
    • git status:“在主分支上”或“HEAD 分离”
    • 分离 HEAD 状态
    • git log:(HEAD -> main)
    • 合并冲突:<<<<<<< HEAD很令人困惑
  • 关于术语一致性的一些想法
  • 就这样!

背景

一般上讲当说某个话题令人困惑而我认为它并不令人困惑时,原因是其中实际上存在一些我没有考虑到的隐藏复杂性。我发现这HEAD 实际上比我想象的要复杂一些!

HEAD 实际上是一些不同的东西

在与许多不同的人谈论之后HEAD,我意识到 HEAD实际上有几个不同的密切相关的含义:

1)文件 .git/HEAD
2)HEAD就像这样git show HEAD(git 称之为“修订参数”)
3)git 在各种命令HEAD的输出中使用的所有方法( <<<<<<<<<<HEAD、、、、等)(HEAD -> main)detached HEAD stateOn branch main
4)它们彼此之间极其密切相关,但我认为对于刚开始使用 git 的人来说,这种关系并不完全明显。

文件 .git/HEAD

Git 有一个非常重要的文件,叫做.git/HEAD。此文件的工作方式是,它包含以下内容之一:

1)分支的名称(如ref: refs/heads/main)
2)提交ID(例如96fa6899ea34697257e84865fefc56beb42d6390)
此文件决定了 Git 中的“当前分支”。例如,当你运行git status并看到以下内容时:
$ git status
On branch main

这意味着该文件 .git/HEAD 包含 ref: refs/heads/main

如果.git/HEAD 包含的是提交 ID 而不是分支,git 会将其称为“分离的 HEAD 状态”。我们稍后会讲到这一点。

(有时会说 HEAD 包含引用 的名称或提交 ID,但我很确定该引用必须是一个分支。从技术上讲,可以.git/HEAD 通过手动编辑来包含非分支的引用的名称.git/HEAD,但我不认为可以使用常规 git 命令来做到这一点。我很想知道是否有一种常规 git 命令方法可以使 .git/HEAD 成为非分支引用,如果是的话,为什么要这样做!)

HEAD如同git show HEAD

HEAD在 git 命令中引用提交 ID是很常见的,例如:
git diff HEAD
git rebase -i HEAD^^^^
git diff main..HEAD
git reset --hard HEAD@{2}

所有这些(HEAD、HEAD^^^、HEAD@{2})都称为“修订参数”。它们记录在man gitrevisions中,Git 会尝试将它们解析为提交 ID。

老实说,我以前从未听说过“修订参数”这个术语,但这个术语可以让你了解这个概念的文档

HEAD 的git show HEAD含义非常简单:它解析已检出的当前提交HEAD!Git以两种方式之一解析:

  1. 如果.git/HEAD包含分支名称,它将是该分支上的最新提交(例如通过从中读取.git/refs/heads/main)

    2)如果.git/HEAD包含提交 ID,则为该提交 ID

下一步:所有输出格式

现在我们已经讨论了文件.git/HEAD 和“修订参数” HEAD。我们剩下的就是 git在其输出中git show HEAD使用的各种方式。HEAD

git status:“在主分支上”或“HEAD 分离”

当运行时git status,第一行将始终看起来像以下两行之一:

on branch main。这意味着.git/HEAD包含一个分支。
HEAD detached at 90c81c72。这意味着.git/HEAD包含一个提交 ID。现在我来解释“HEAD detached”是什么意思。

分离 HEAD 状态

“HEAD 已分离”或“HEAD 分离状态”意味着您没有当前分支。

没有当前分支有点危险,因为如果你做了新的提交,这些提交将不会附加到任何分支 - 它们将被孤立!孤立提交是个问题,原因有 2 个:

1)提交更难找到(你不能跑去git log somebranch寻找它们)
2)孤立的提交最终将被 git 的垃圾收集删除

就我个人而言,我非常小心地避免在分离的 HEAD 状态下创建提交,尽管有些人更喜欢这样工作。但是,退出分离的 HEAD 状态非常容易,您可以:

1)返回分支 ( git checkout main)

2)在该提交处创建一个新分支(git checkout -b newbranch)

3)如果你处于分离 HEAD 状态,因为你正处于变基过程中,请完成或中止变基(git rebase --abort)

好的,回到其他 git 命令的HEAD输出!

git log:(HEAD -> main)

当您运行git log并查看第一行时,可能会看到以下 3 种情况之一:

commit 96fa6899ea (HEAD -> main)
commit 96fa6899ea (HEAD, main)
commit 96fa6899ea (HEAD)

目前还不太清楚如何解释这些,所以情况是这样的:

在 中(…),git 列出了指向该提交的每个引用,例如(HEAD -> main, origin/main, origin/HEAD)表示HEAD、main、origin/main和origin/HEAD都指向该提交(直接或间接)
HEAD -> main意味着你当前的分支是main
如果该行显示的是HEAD,而不是HEAD ->,则表示您处于分离的 HEAD 状态(您没有当前分支)
如果我们用这些规则来解释上面的3个例子:结果是:

1)commit 96fa6899ea (HEAD -> main)方法:
   1-1).git/HEAD包含ref: refs/heads/main
   1-2).git/refs/heads/main包含96fa6899ea
 
2)commit 96fa6899ea (HEAD, main)方法:
   2-1).git/HEAD包含96fa6899ea(HEAD 处于“分离”状态)
   2-2).git/refs/heads/main还包含96fa6899ea
 
3)commit 96fa6899ea (HEAD)方法:
   3-1).git/HEAD包含96fa6899ea(HEAD 处于“分离”状态)
   3-2).git/refs/heads/main包含不同的提交 ID 或不存在

合并冲突:<<<<<<< HEAD很令人困惑

当您解决合并冲突时,您可能会看到类似以下内容:

<<<<<<< HEAD
def parse(input):return input.split("\n")
=======
def parse(text):return text.split("\n\n")
>>>>>>> somebranch

我发现HEAD这种情况非常令人困惑,我基本上只是忽略它。原因如下:

  1. 当你进行合并时,合并冲突与运行时的HEAD冲突相同。很简单。HEAD git merge

2)当你执行rebase时,HEAD合并冲突是完全不同的:这是你正在 rebase 的另一个提交HEAD。所以它与你运行 时的情况完全不同git rebase。之所以如此,是因为 rebase 的工作方式是先检出另一个提交,然后反复在其上挑选提交。

类似地,“我们的”和“他们的”的含义在合并和变基时被颠倒了。

事实上,HEAD根据我是否进行变基或合并而改变的含义对我来说确实太令人困惑了,我发现完全忽略HEAD并使用另一种方法来找出代码的哪部分是哪部分要简单得多。

关于术语一致性的一些想法

我认为,如果 git 围绕 HEAD 的术语在内部更加一致,那么 HEAD 会更加直观。

例如,git 会谈论“分离的 HEAD 状态”,但从不谈论“连接的 HEAD 状态”——git 的文档从来没有使用术语“连接”来指代HEAD。git 会谈论“在”分支上,但从不谈论“不在”分支上。

因此很难猜测 on branch main实际上是的反义词 HEAD detached。用户如何猜测这HEAD detached和分支有什么关系,或者和“在主分支上”有什么关系HEAD?

就这样!

如果我想到HEAD在 Git 中使用其他方法(尤其是 HEAD 出现在 Git 输出中的方式)会继续补充进来,如果你觉得 HEAD 令人困惑,我希望这篇文章有所帮助!

这篇关于git中的head到底是怎么工作的,十分钟就够了的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1124351

相关文章

IDEA中新建/切换Git分支的实现步骤

《IDEA中新建/切换Git分支的实现步骤》本文主要介绍了IDEA中新建/切换Git分支的实现步骤,通过菜单创建新分支并选择是否切换,创建后在Git详情或右键Checkout中切换分支,感兴趣的可以了... 前提:项目已被Git托管1、点击上方栏Git->NewBrancjsh...2、输入新的分支的

一文详解Git中分支本地和远程删除的方法

《一文详解Git中分支本地和远程删除的方法》在使用Git进行版本控制的过程中,我们会创建多个分支来进行不同功能的开发,这就容易涉及到如何正确地删除本地分支和远程分支,下面我们就来看看相关的实现方法吧... 目录技术背景实现步骤删除本地分支删除远程www.chinasem.cn分支同步删除信息到其他机器示例步骤

SpringBoot集成LiteFlow工作流引擎的完整指南

《SpringBoot集成LiteFlow工作流引擎的完整指南》LiteFlow作为一款国产轻量级规则引擎/流程引擎,以其零学习成本、高可扩展性和极致性能成为微服务架构下的理想选择,本文将详细讲解Sp... 目录一、LiteFlow核心优势二、SpringBoot集成实战三、高级特性应用1. 异步并行执行2

怎么用idea创建一个SpringBoot项目

《怎么用idea创建一个SpringBoot项目》本文介绍了在IDEA中创建SpringBoot项目的步骤,包括环境准备(JDK1.8+、Maven3.2.5+)、使用SpringInitializr... 目录如何在idea中创建一个SpringBoot项目环境准备1.1打开IDEA,点击New新建一个项

Spring @Scheduled注解及工作原理

《Spring@Scheduled注解及工作原理》Spring的@Scheduled注解用于标记定时任务,无需额外库,需配置@EnableScheduling,设置fixedRate、fixedDe... 目录1.@Scheduled注解定义2.配置 @Scheduled2.1 开启定时任务支持2.2 创建

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

qt5cored.dll报错怎么解决? 电脑qt5cored.dll文件丢失修复技巧

《qt5cored.dll报错怎么解决?电脑qt5cored.dll文件丢失修复技巧》在进行软件安装或运行程序时,有时会遇到由于找不到qt5core.dll,无法继续执行代码,这个问题可能是由于该文... 遇到qt5cored.dll文件错误时,可能会导致基于 Qt 开发的应用程序无法正常运行或启动。这种错

电脑提示xlstat4.dll丢失怎么修复? xlstat4.dll文件丢失处理办法

《电脑提示xlstat4.dll丢失怎么修复?xlstat4.dll文件丢失处理办法》长时间使用电脑,大家多少都会遇到类似dll文件丢失的情况,不过,解决这一问题其实并不复杂,下面我们就来看看xls... 在Windows操作系统中,xlstat4.dll是一个重要的动态链接库文件,通常用于支持各种应用程序

LiteFlow轻量级工作流引擎使用示例详解

《LiteFlow轻量级工作流引擎使用示例详解》:本文主要介绍LiteFlow是一个灵活、简洁且轻量的工作流引擎,适合用于中小型项目和微服务架构中的流程编排,本文给大家介绍LiteFlow轻量级工... 目录1. LiteFlow 主要特点2. 工作流定义方式3. LiteFlow 流程示例4. LiteF

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte