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

相关文章

MySql死锁怎么排查的方法实现

《MySql死锁怎么排查的方法实现》本文主要介绍了MySql死锁怎么排查的方法实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录前言一、死锁排查方法1. 查看死锁日志方法 1:启用死锁日志输出方法 2:检查 mysql 错误

Rsnapshot怎么用? 基于Rsync的强大Linux备份工具使用指南

《Rsnapshot怎么用?基于Rsync的强大Linux备份工具使用指南》Rsnapshot不仅可以备份本地文件,还能通过SSH备份远程文件,接下来详细介绍如何安装、配置和使用Rsnaps... Rsnapshot 是一款开源的文件系统快照工具。它结合了 Rsync 和 SSH 的能力,可以帮助你在 li

Git提交代码详细流程及问题总结

《Git提交代码详细流程及问题总结》:本文主要介绍Git的三大分区,分别是工作区、暂存区和版本库,并详细描述了提交、推送、拉取代码和合并分支的流程,文中通过代码介绍的非常详解,需要的朋友可以参考下... 目录1.git 三大分区2.Git提交、推送、拉取代码、合并分支详细流程3.问题总结4.git push

电脑密码怎么设置? 一文读懂电脑密码的详细指南

《电脑密码怎么设置?一文读懂电脑密码的详细指南》为了保护个人隐私和数据安全,设置电脑密码显得尤为重要,那么,如何在电脑上设置密码呢?详细请看下文介绍... 设置电脑密码是保护个人隐私、数据安全以及系统安全的重要措施,下面以Windows 11系统为例,跟大家分享一下设置电脑密码的具体办php法。Windo

Git中恢复已删除分支的几种方法

《Git中恢复已删除分支的几种方法》:本文主要介绍在Git中恢复已删除分支的几种方法,包括查找提交记录、恢复分支、推送恢复的分支等步骤,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录1. 恢复本地删除的分支场景方法2. 恢复远程删除的分支场景方法3. 恢复未推送的本地删除分支场景方法4. 恢复

怎么关闭Ubuntu无人值守升级? Ubuntu禁止自动更新的技巧

《怎么关闭Ubuntu无人值守升级?Ubuntu禁止自动更新的技巧》UbuntuLinux系统禁止自动更新的时候,提示“无人值守升级在关机期间,请不要关闭计算机进程”,该怎么解决这个问题?详细请看... 本教程教你如何处理无人值守的升级,即 Ubuntu linux 的自动系统更新。来源:https://

Ubuntu系统怎么安装Warp? 新一代AI 终端神器安装使用方法

《Ubuntu系统怎么安装Warp?新一代AI终端神器安装使用方法》Warp是一款使用Rust开发的现代化AI终端工具,该怎么再Ubuntu系统中安装使用呢?下面我们就来看看详细教程... Warp Terminal 是一款使用 Rust 开发的现代化「AI 终端」工具。最初它只支持 MACOS,但在 20

LinuxMint怎么安装? Linux Mint22下载安装图文教程

《LinuxMint怎么安装?LinuxMint22下载安装图文教程》LinuxMint22发布以后,有很多新功能,很多朋友想要下载并安装,该怎么操作呢?下面我们就来看看详细安装指南... linux Mint 是一款基于 Ubuntu 的流行发行版,凭借其现代、精致、易于使用的特性,深受小伙伴们所喜爱。对

macOS怎么轻松更换App图标? Mac电脑图标更换指南

《macOS怎么轻松更换App图标?Mac电脑图标更换指南》想要给你的Mac电脑按照自己的喜好来更换App图标?其实非常简单,只需要两步就能搞定,下面我来详细讲解一下... 虽然 MACOS 的个性化定制选项已经「缩水」,不如早期版本那么丰富,www.chinasem.cn但我们仍然可以按照自己的喜好来更换

SSID究竟是什么? WiFi网络名称及工作方式解析

《SSID究竟是什么?WiFi网络名称及工作方式解析》SID可以看作是无线网络的名称,类似于有线网络中的网络名称或者路由器的名称,在无线网络中,设备通过SSID来识别和连接到特定的无线网络... 当提到 Wi-Fi 网络时,就避不开「SSID」这个术语。简单来说,SSID 就是 Wi-Fi 网络的名称。比如