git push,现在我有一个超脱的头

时间:2019-02-06 23:08:06

标签: git

我正在一个本地分支 foo 上,该分支具有丰富而有用的历史。我做了很多更改并提交。 git status说:

On branch foo Your branch is ahead of 'origin/foo' by 1 commit. (use "git push" to publish your local commits)

所以我继续输入git push

似乎工作正常。快速git status显示:

On branch foo Your branch is up to date with 'origin/foo'. nothing to commit, working tree clean

我切换到本地主要主分支(称为 feature1 git checkout feature1。没问题。然后,我git pull添加所有同事的更改。

现在我想切换回 foo ,以合并我刚刚放入 foo feature1 更改。

编辑(我在键入和发帖时都错过了!这是关键!!)

git checkout origin\foo

瞧瞧!我收到了我从未见过的消息:

Note: checking out 'origin/foo'.

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 f5a29b1083 cosmetic changes for code review

现在git status的结果是

编辑(更正):

HEAD detached at origin/foo
nothing to commit, working tree clean

所以我的问题有多个:

1)我做错了什么?这是我已经做了很长时间的事情了,但是以前从未发生过这样的事情。

2)如何确保不会再次发生这种情况?

3)在将来将 foo 合并到 feature1 中时,如何解决此问题而又不丢失我的工作,(更重要的是)又不污染每个人的历史?

2 个答案:

答案 0 :(得分:1)

每次编辑:嗯,您实际上运行了git checkout origin/foo。 (反斜杠的拼写特定于Windows,但是这种斜杠的变体在任何地方都可以使用。)

git checkout命令首先尝试使用您给它命名的任何名称作为分支名称,即refs/heads/whatever。如果该方法有效(如果它是有效的分支名称),则Git会检查该分支的尖端提交,并在该分支上附加HEAD ,这样您就可以将{{ 1}}将其放置。

但是,如果不存在全名git status的分支 ,Git最终将根据the gitrevisions documentation中概述的六步过程尝试解析该名称。此过程最终会在您的情况下找到refs/heads/whatever。那不是 分支名称,但有效的提交哈希,因此Git将该特定提交作为“分离的HEAD”进行签出。 Git不会将分支名称存储在refs/remotes/origin/foo中,而是存储提交的原始哈希ID。

最终,所有这些都依赖于Git中HEAD的双重性质:它是 current分支 current提交。为此,Git通常将分支名称写入HEAD中,并使用分支名称本身来记录提交哈希。这就是“附加的HEAD”案例。为了支持转移分支,Git愿意将原始提交哈希ID写入HEAD

您可以问Git: HEAD是哪个分支的名称?使用HEAD。这将从git symbolic-ref HEAD中获取名称,而没有获取提交ID。如果您处于HEAD分离模式,则会出现错误。

或者,您可以问Git: HEAD使用HEAD来表示什么提交哈希ID?。这将从git rev-parse HEAD获取提交哈希ID,如果您处于附加头模式,则使用分支名称;如果处于分离头模式,则使用原始哈希ID。无论哪种方式都可以。 (在HEAD包含分支名称,但分支不存在的罕见但并非不可能的情况下,此方法失败。这种情况在新的完全空的存储库中是正常的,可以通过{{1} }。

(注意:有一个中间步骤,其中HEAD尝试创建分支名称。有时称为“ DWIM选项”或“执行我的意思”。查看所有的远程跟踪名称,以查看是否有与您提供的名称完全匹配的名称,除了其中的git checkout --orphan


要发生这种情况,您的git checkout目录中必须有一个名为origin/的文件。该文件必须包含以下文本:

.git

,或者是指向foo的符号链接。要查看哪个,请尝试:

ref: refs/remotes/origin/foo

和:

refs/remotes/origin/foo

此外,必须不要是名为ls -l .git/foo 分支,因为Git希望使用分支而不是文件/符号链接:

cat .git/foo

但是:

foo

(删除$ git checkout diff-merge-base Switched to branch 'diff-merge-base' $ ln -s refs/remotes/origin/master .git/master $ git checkout master warning: refname 'master' is ambiguous. Switched to branch 'master' Your branch is up to date with 'origin/master'. 并使用$ rm .git/master $ echo 'ref: refs/remotes/origin/master' > .git/foo $ git checkout foo Note: checking out 'foo'. 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 ... [snip] $ git status HEAD detached at origin/master nothing to commit, working tree clean 可以使一切正确。)

这一切如何发生在您的.git/foo目录内 。

答案 1 :(得分:0)

  1. 发布时
let
Source = Excel.Workbook(File.Contents("\\share\path\to\my\other\Workbook.xlsx"), null, true){[Item="tblPX",Kind="Table"]}[Data] 
in
Source

这与本地 git checkout origin/foo 分支冲突。

  1. 您可以只foo,也可以删除当前的 foo 分支,然后再次签出;

  2. 您不会失去工作。