首页 > 解决方案 > git pull --rebase origin HEAD 拉错分支。HEAD 代表什么?

问题描述

我的团队压缩功能提交并重新设置主分支以保持我们的历史线性。

对于这个问题,假设我们有 3 个分支

git checkout dev
git checkout -b my-feature
// do work
git commit -m "some work"
// another commit merges/is added to dev
git pull --rebase origin dev
git push origin HEAD

最后一个命令将当前分支推送到删除分支。

现在假设我正在做一个部署

git checkout prod

git status
On branch prod
Your branch is behind 'remotes/origin/prod' by 2 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)

nothing to commit, working tree clean

git pull --rebase origin HEAD
From xxx
 * branch              HEAD       -> FETCH_HEAD
Successfully rebased and updated refs/heads/prod.

git status
On branch prod
Your branch is ahead of 'remotes/origin/prod' by 3 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

为什么我在分支时git pull --rebase origin HEAD从分支中拉出?这正常吗?devprod

如果我离开 HEAD,我会得到我所期望的(prod == origin/prod) git pull --rebase origin

我注意到当我在我的功能分支上时.git/HEAD,我所期望的价值......

git checkout my-feature
cat .git/HEAD
ref: refs/heads/my-feature

git checkout prod
cat .git/HEAD
ref: refs/heads/dev

所以问题是,为什么分支HEAD不同?prod

我经常用 推送我的功能分支 git push -f origin HEAD,所以我真的不想找到它试图推送到我们的开发分支的一天。

我认为这无关紧要,但我们使用 GitLab 作为我们的主机。

这个问题很相似,但所有最重要的答案都描述了我所经历的相反

  • HEAD 只是一个特殊的指针,指向您当前所在的本地分支。
  • Head 是你当前的分支
  • HEAD 总是指当前分支上的最新提交。
  • HEAD 是当前分支的“尖端”。
  • HEAD 是一个符号引用,指向您在提交历史中的任何位置。

所以问题是,为什么会发生这种情况:

git checkout prod
cat .git/HEAD
ref: refs/heads/dev

标签: gitgitlabpull

解决方案


使用对多个引用进行操作的 git 命令时,请参阅具体的 git 引用。例如,如果您打算使用 .dev来代替.HEADdev

当您执行诸如( What is HEAD in Git? )等HEAD命令时,git 会写入文件(和引用),并且可以在 gits 的要求下突然改变含义。git checkoutgit rebase

HEAD期间将改变含义,git rebase因为(在您的情况下)git 将签出dev(并写入文件devHEAD,即使您从 执行命令prod)并从中挑选所有提交prod(以及根据git rebase https://工作的后续事件) git-scm.com/docs/git-rebase


推荐阅读