Git:dev和refs/heads/dev有什么区别?

Git: what is the difference between dev and refs/heads/dev?

从最近在 devops 的工作来看,似乎有“两种方法”来检查 git 中的分支:使用普通分支名称,例如dev,或使用前缀为 refs/heads/ 的分支名称,例如refs/heads/dev.

两者有什么区别?

Jenkins 的 Bitbucket webhook 中的某些 HTTP POST 内容给出了分支的“refs/head”版本。其他POST内容给出了“basename”分支。
例如。使用(我认为是)Jenkins 语法从拉取请求 Bitbucket 事件中获取 POST 内容,$.pullRequest.fromRef.id == /refs/heads/dev...
$.pullRequest.fromRef.displayId == dev

在克隆的存储库中,检出 refs/heads/devdev 解析为相同的 SHAID,但它们各自的 stdout 不同:

$ git checkout refs/heads/dev
Note: checking out 'refs/heads/dev'.

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 performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at c320fd1... wip
$ git checkout dev
Switched to branch 'dev'
Your branch is up-to-date with 'origin/dev'.
$ git log --oneline -n 1
c320fd1 wip

前者的 stdout 看起来和你检查 SHAID 时一样。

根据 the rules in the docs.

,名称会提前解析为修订版 ID

当你给出的 ref 通过(仅)添加 refs/heads/ 前缀来解析时,Git 的便利机制开始运行,git checkout 将使 HEAD 成为分支提示的别名,因此所有依赖 HEAD 的便捷命令都将引用并更新分支提示 ref.

所以当你说 git checkout dev 时,你正在使用 Git 的便利机制,它为你做了方便的事情,它连接 HEAD 成为对refs/heads/devgit commitHEAD 更新将重定向到该分支提示。

但是,如果您通过自己采取明确的步骤来绕过便利逻辑,则不会发生这种情况。这真的是唯一的区别。如果你愿意,你可以

git checkout refs/heads/dev 
git symbolic-ref HEAD refs/heads/dev

现在您已经完成了 Git 的便利处理。