是否有一个或多个Git Head?

oewdyzsn  于 2023-10-14  发布在  Git
关注(0)|答案(2)|浏览(112)

我实际上是在尝试深入了解Git的核心概念。最近我对GitHEAD指针很感兴趣。
我知道HEAD是一个指向分支(间接指向提交)或直接指向提交的指针。如果我的理解是正确的话,这就是连接和分离的HEAD之间的区别。这个主题帮助我澄清了我在这个问题上的大多数问题:What is HEAD in Git?
但有一个问题我还没有找到答案。
如果我在一个分支A上并且 checkout 到一个过去的提交,那么我在这个提交上有一个分离的HEAD。如果我 checkout 到一个分支B,那么HEAD就在这个分支的最后一次提交上。如果我回到分支A,似乎HEAD仍然在我之前到达的过去的提交上。
所以我在想:它是否存在一个和唯一的头指针,保持跟踪他以前的位置在每个分支或它是否存在多个头指针的多个分支?
我在一个Git项目上做了多次移动,以了解其行为,并在网络上查看了多次Stack Overflow问题和文章,以从理论上理解HEAD的概念。但我没有找到任何明确的答案。

gdx19jrr

gdx19jrr1#

每个存储库只有一个HEAD符号引用(如果您使用的是worktree,则每个worktree)。符号引用的目标存储在文件.git/HEAD中。(只有一个文件只有一行,所以只能有一个HEAD)。
如果您现在已经 checkout 了分支master,则会看到以下内容:

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

detached HEAD 状态下,它看起来像这样:

$ cat .git/HEAD
0123456789abcdef0123456789abcdef01234567
f0brbegy

f0brbegy2#

是的,只有一个HEAD。[1]你对HEAD如何工作以及分支(refs/heads/*引用)如何工作的理解是正确的。
如果你做像git checkout <branch>git checkout <SHA1>这样的事情,那么这就是它的全部。没有必要记住任何东西。
但是你也可以使用特殊的revision syntax,比如:

# Where `HEAD` was five moves ago
git checkout HEAD@{5}
# Where `HEAD` was at that time
git checkout HEAD@{5.minutes.ago}
# Where `HEAD` was last (like `cd -`)
git checkout -

Git在这个例子中使用的是一个 reflog,它是一个记录引用位置的日志(每个条目一行)。例如,每次执行git checkoutgit reset <mode> <commitish>时都会更新。
因此,如果启用了reflog,Git会记住HEAD的位置。
reflog也会记住同样的分支:

git checkout main@{5}
git checkout main@{5.minutes.ago}

因为每个分支都有自己的reflog,就像HEAD有自己的reflog一样。
如果您将core.logAllRefUpdates设置为true,则还可以记录其他类型的ref移动。

注意事项

1.每个Git工作树都有自己的HEAD,但如果你不知道它是什么,那么它在任何情况下都不重要

相关问题