当我从有新文件的本地分支执行 git 提取和 git 检出 origin/branch 时实际发生了什么?

What happens actually when I do git fetch and git checkout origin/branch from a local branch where new files are there?

假设我有一个本地分支 A 和两个远程分支 AB
local 分支 A 包含 一些文件 不在 remote B.
然后,我做如下:

git fetch
git checkout origin/B

then, those files from local A remains there, I removed those files and commit with my required changes in some files which were there in origin/B:

git add .
git commit -m "fixes made"

then, head got detached with showing the commit hash

所以,我有两个问题

  1. 为什么那些文件来自我本地的分支 A copied/remained to/in origin/B?

  2. 为什么头掉了?

Why those files from my local branch A copied/remained to/in origin/B?

因为它们不是 来自分支 A 的文件。它们是您工作目录中不受 git 管理的文件。您没有将它们添加到分支 A 或其他任何地方的任何提交中。 git 不会对未被告知要管理的文件执行任何操作。工作不是 "on a branch" 直到你提交它。

Why head got detached?

因为你做了 git checkout origin/B,这使得 HEAD 分离。您可能是指 git checkout -t origin/B,它创建了一个新分支 B,其上游为 origin/B 并指向 HEAD 那里。

@hobbs already gave you the .

回答中的问题:

Each branch will have different HEAD. So how that actually happens?

在 Git 中,单词 HEAD(大写)并不像您所期望的那样表示“the tip of the branch1;相反,HEAD 是一个特殊的引用,指向您当前在工作目录中检出的分支。

documentation 说得最好:

A single Git repository can track an arbitrary number of branches, but your working tree is associated with just one of them (the "current" or "checked out" branch), and HEAD points to that branch.

通常HEAD 指向分支名称2,但它也可以指向特定的提交。当发生这种情况时,它被称为“detached HEAD”。

现在,由于您不能直接提交给 remote tracking branch,当您说:

git checkout origin/B

HEAD 最终 直接 指向 origin/B 引用的提交,而不是本地分支名称;因此,它变成了一个 分离的 HEAD.


  1. 这叫做 "head",小写。
  2. 事实上,.git 目录中有一个名为 HEAD 的文本文件,其中包含它指向的分支的名称。