git checkout remotes/origin/branch 和 git checkout branch 有什么区别?

What is difference between git checkout remotes/origin/branch and git checkout branch?

当我执行

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

谁能解释一下有什么区别,为什么在分支相同的情况下会进入分离状态?

分支相同。

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

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

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

与传统的版本控制系统不同,Git 不会习惯性地与中央服务器对话。您拥有存储库及其所有历史记录的完整副本。除了 git pullgit pushgit fetch.

等少数命令外,所有命令都在本地发生

相反,Git 使用 "remote tracking branches" 跟踪远程存储库的状态。这些就像普通的分支一样,只是它们标记了它在远程服务器上最后一次看到分支的地方,你不能提交给它们。这些会在您执行 git fetch 时更新,这是 git pull.

的一部分

(要知道的重要事情之一是 Git "branch" 只不过是指向提交的标签。)

test_branch 是您存储库中的本地分支。 remotes/origin/test_branch,通常称为 origin/test_branch,是您上次执行 git fetch 时名为 origin 的遥控器上名为 test_branch 的分支的位置。如果它们是相关的,test_branch 将有 origin/test_branch 作为它的上游。

当您 git checkout test_branch git 签出 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_branch git 签出 origin/test_branch 指向的提交时,将 HEAD 移动到该提交(HEAD 跟踪当前签出的提交commit)... 因为它是一个远程跟踪分支。你不再在一个分支上,你处于 "detached 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

有关更多信息,请参阅 Working with Remotes