令人困惑的 git 术语

HEAD and "heads"

一些人表示他们对术语 HEADrefs/heads/main 感到困惑

其实 "头"就是"枝"。在 git 内部,分支存储在名为 .git/refs/heads 的目录中

HEAD 是当前分支。它存储在 .git/HEAD 中。

"a head 是一个分支, HEAD 是当前分支" 这绝对是 git 中最奇怪的术语之一。

Your branch is up to date with 'origin/main'

你的分支已更新为'origin/main' ?

此消息看起来很简单 - 它表示你的 main 分支已与源保持同步!

但这实际上有点误导。你可能认为这意味着你的 main 分支是最新的。事实并非如此。

它实际上意味着 -- 如果你上次运行 git fetch 或 git pull 是在 5 天前,那么 5 天前你的 main 分支是最新的(包含 5 天前的所有更改)

说白了,只是上次同步过,但上一次是什么时候可不好说了,如果你没有意识到这一点,它可能会给您一种错误的安全感。

我认为 git 理论上可以给你一条更有用的消息,比如"截至 5 天前最后一次获取,源的 main 是最新的"

HEAD^, HEAD~ HEAD^^, HEAD~~, HEAD^2, HEAD~2

我知道 HEAD^ 指的是之前的提交,但我对 HEAD~HEAD^ 的区别困惑了很久。

我查了一下,以下是它们之间的关系:

  • HEAD^HEAD~ 是一样的(1 次提交前)
  • HEAD^^^HEAD~~~HEAD~3 是一样的(3 次提交前)
  • HEAD^3 指提交的第三个父级,与 HEAD~3 不同

这看起来很奇怪------为什么 HEAD~HEAD^ 是一样的?

"第三父级" 又是什么呢?

^~ 在 Git 中用于导航提交树。

  • ^ 用于访问合并提交的不同父提交
  • ~ 用于访问当前提交的祖先提交

大多数提交只有一个父提交。在 Git 中 HEAD^ 表示"HEAD 提交的父级"。

但是如果 HEAD 是合并提交, HEAD^ 指的是合并的第一个父级, HEAD^2 是第二个父级, HEAD^3 是第三个父级,依此类推。

通常,这种语法在合并提交(merge commit)时使用,其中有多个父提交。例如,一个合并提交可能有两个父提交,通过 HEAD^1 和 HEAD^2 可以访问这两个父提交。HEAD^3 就表示第三个父提交。

HEAD~3: 表示从 HEAD 开始往上数的第三个祖先提交。它指的是当前分支的前第三个提交,不考虑合并提交。这在查看历史记录时很有用。

"reset", "revert", "restore"

很多人提到 "reset"、"revert" 和 "restore" 是非常相似的词,很难区分它们。

手册也没有提供非常有用的信息:

  • git reset : "重置当前 HEAD 到指定状态"
  • git revert :"恢复一些现有的提交"
  • git restore :"恢复工作树文件"

以下是它们各自的作用的一些简短描述:

  • git revert COMMIT :在当前分支上创建一个与 COMMIT "相反"的新提交(如果 COMMIT 添加了 3 行,则新提交将删除这 3 行)

  • git reset --hard COMMIT :强制当前分支返回到 COMMIT 时的状态,删除自 COMMIT 以来的所有新更改。非常危险的操作。

  • git restore --source=COMMIT PATH :将 PATH 中的所有文件恢复到 COMMIT 时的状态,而不更改任何其他文件或提交历史记录。

main 和 origin/main

在 Git 中,mainorigin/main 分别表示不同的引用。

main: 这是本地分支的名称,通常表示你当前所在的本地分支,例如,如果你切换到主分支,那么 main 就代表本地主分支。

css 复制代码
git checkout main

这表示你正在引用本地仓库中的 main 分支。

origin/main: 这是远程仓库的引用,通常表示远程主分支。origin 是默认的远程仓库名称,而 main 则表示在该远程仓库上的主分支。

bash 复制代码
git fetch origin
git checkout origin/main

这表示你正在引用远程仓库 origin 上的 main 分支。请注意,你不能在 origin/main 上直接进行修改,因为它是只读的,你需要在本地分支上进行工作。

在典型的 Git 工作流中,你通常会从远程仓库克隆(clone)代码,本地会自动创建一个名为 main 的主分支,并在远程仓库上创建一个名为 origin/main 的引用。在进行协作开发时,你可能会通过 git pullgit fetch 来同步远程仓库的最新更改,这时就会涉及到本地的 main 分支和远程的 origin/main 引用。

checkout

  • git checkout BRANCH 切换分支
  • git checkout file.txt 放弃对 file.txt 的更改,恢复为上一次提交(最新提交)的版本。

checkout 后面跟分支名和文件名作用是不一样的,呵呵。

git checkout file.txt 这条命令的效果相当于取消对 file.txt 的本地修改,将其还原为最新提交的状态。不过,git checkout 在 Git 2.23 版本之后的版本中被 git restore 和 git switch 命令替代,因此你也可以使用以下等效的命令:

csharp 复制代码
# 使用 git restore
git restore file.txt

# 或者使用 git switch
git switch --discard-changes file.txt
相关推荐
裸奔的大金毛18 小时前
Tekton - 自定义镜像配置git仓库克隆
git·ci/cd·devops·tekton
Adorable老犀牛21 小时前
可遇不可求的自动化运维工具 | 2 | 实施阶段一:基础准备
运维·git·vscode·python·node.js·自动化
xiaok1 天前
把代码上传到gitee的时候,怎么忽略node_modules文件夹
git·gitlab·github
唐叔在学习1 天前
听说有老哥分不清Git branch和tag?这不看看嘛
git·后端
雁于飞1 天前
vscode中使用git、githup的基操
笔记·git·vscode·学习·elasticsearch·gitee·github
小毛驴8502 天前
所有微服务部署都使用一个git地址,并且通过docker部署各个服务的情况下,如何编写mvn指令来处理各个服务。
git·docker·微服务
国王不在家2 天前
git 切换仓库后清理分支缓存
git
柯南二号2 天前
【Gitlab】Ubuntu 20.04服务器部署Gitlab
git·gitlab
phac1232 天前
git 如何直接拉去远程仓库的内容且忽略本地与远端不一致的commit
大数据·git·elasticsearch
ficker132 天前
git常用命令
git