1

当我执行

git checkout remotes/origin/test_branch

我的 HEAD 处于分离状态。下面是输出:

C:\..\git_test>git checkout remotes/origin/test_branch
Note: checking out 'remotes/origin/test_branch'.

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 4590fa2 Test branch commit
M       src/test/resources/**

C:\..\git_test>git branch -a
* (HEAD detached at origin/test_branch)
  test_branch
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/test_branch
  remotes/origin/master

如果我执行

git checkout test_branch

在同一个分支上,我不再处于分离状态。

C:\..\git_test>git checkout test_branch
Switched to branch 'test_branch'
M       src/test/resources/**
Your branch is up to date with 'origin/test_branch'.

C:\..\git_test>git branch -a
* test_branch
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/test_branch
  remotes/origin/master

请任何人都可以解释有什么区别以及为什么它会在分支相同的情况下进入分离状态?

4

2 回答 2

3

分支一样。

<branch>是您的本地版本。一个实际的分支。

remotes/origin/<branch>是一个远程跟踪分支。您无法直接控制这些,它们会自动更新fetch,它们是远程分支的图像,以便进行比较。

你不应该检查这些,因为承诺它们或移动它们的位置会破坏它们的目的。如果你确实尝试过(就像你做的那样),git 会做下一件最好的事情,它会检查这个引用指向的提交。导致分离的 HEAD 状态。

于 2020-01-24T08:19:54.397 回答
2

与传统的版本控制系统不同,Git 不习惯与中央服务器通信。您拥有存储库及其所有历史记录的完整副本。所有命令都在本地发生,除了少数像git pull,git pushgit fetch.

相反,Git 使用“远程跟踪分支”来跟踪远程存储库的状态。这些就像普通的分支,除了它们标记了它在远程服务器上看到分支的最后一个位置,并且你不能提交它们。当您这样做时,这些会更新,git fetch这作为git pull.

(要知道的重要事情之一是 Git “分支”只不过是指向提交的标签。)

test_branch是存储库中的本地分支。remotes/origin/test_branch,通常称为,是您最后一次调用远程调用的origin/test_branch分支的位置。如果它们是相关的,将作为其上游。test_branchorigingit fetchtest_branchorigin/test_branch

当您git checkout test_branchgit 签出提交test_branch所指向的内容时,移动HEAD到该提交(HEAD跟踪当前签出的提交),并将您标记为在test_branch.

如果git commit你提前HEADtest_branch.

git checkout master

              [HEAD]
A - B - C - D [master]
         \
          E - F [test_branch]

git checkout test_branch

A - B - C - D [master]
         \
          E - F [test_branch]
                [HEAD]

git commit -a

A - B - C - D [master]
         \
          E - F - G [test_branch]
                    [HEAD]

当您git checkout origin/test_branchgit 检查提交origin/test_branch所指向的内容时,移动HEAD到该提交(HEAD跟踪当前签出的提交)......并且因为它是一个远程跟踪分支。您不再在分支上,而是处于“分离的 HEAD”状态。

如果您git commit前进HEAD,但origin/test_branch仍然保持原状。

git checkout master

              [HEAD]
A - B - C - D [master]
         \
          E - F [origin/test_branch]

git checkout origin/test_branch

A - B - C - D [master]
         \
          E - F [origin/test_branch]
                [HEAD]

git commit -a

A - B - C - D [master]
         \
          E - F [origin/test_branch]
               \
                G [HEAD]

由于没有关联的分支,因此没有任何内容涉及此新提交。如果你这样做了,git checkout master那么G它就会悬空,实际上会丢失,尽管可以使用git reflog.

git checkout master

              [HEAD]
A - B - C - D [master]
         \
          E - F [origin/test_branch]
               \
                G

有关更多信息,请参阅使用遥控器

于 2020-01-24T08:24:24.717 回答