0

我使用创建了一个工作树git worktree add,它按预期工作了几天。今天想看看上个版本的一些代码,所以暂时分离了HEAD

git checkout head^

在我找到我需要的东西之后,我试图回到我的工作树分支的顶端:

git checkout <branchname>

但是现在,HEAD指向我本地master分支中的最高提交。例如:

git show head

显示master.

任何想法为什么会发生这种情况或如何解决它?


编辑

我还看到一些奇怪的、不一致的行为。例如,这个:

> git reset --hard
HEAD is now at 4f1666467017
> git rev-parse head
e4fab17872cce2f6f37f5b596c7ed2739b135f3f
4

1 回答 1

0

(注意:其中一些是通用的。)

这里的额外怪异可能与每个工作树都有自己的私有HEAD文件这一事实有关。不同的操作可能会HEAD通过 case-folding 找到不同的文件:添加的工作树有一个文件,主工作树有一个文件。如果操作A选择匹配,而操作B选择,您会看到这种行为。使用全大写应该让 Git 做正确的事。.git/worktrees/worktree/HEAD.git/HEAD.git/HEADhead.git/worktrees/worktree/HEADHEAD

(特别是,git reset --hard内部使用HEAD所有大写字母,这将引用 per-work-tree HEAD,而git rev-parse head使用小写字母head,它将引用.git/HEAD文件。)


您可以通过其原始哈希 ID 检查任何历史提交:

git checkout a123456

结果就是 Git 所说的分离的 HEAD。通常,特殊名称HEAD(全部大写)附加到分支名称:

...--A--B--C--D   <-- master (HEAD)
         \
          E--F--G   <-- branch

(这里的大写字母代表实际的提交哈希 ID)。通过像这样被附加,HEAD意味着master这意味着 commit D。因此,您当前的提交现在就是 commitD的真实哈希 ID。如果你运行:

git checkout branch

你得到:

...--A--B--C--D   <-- master
         \
          E--F--G   <-- branch (HEAD)

这意味着您当前的分支branch并且您当前的提交是 now G

但是,当您通过哈希 ID 选择提交时——比如说提交E——你HEAD直接指向那个提交:

...--A--B--C--D   <-- master
         \
          E   <-- HEAD
           \
            F--G   <-- branch

这就是 Git 所说的“分离的 HEAD”;您当前的提交是 commit E

现在,您没有使用原始哈希 ID。相反,您输入了head^. 但是有很多方法可以命名提交。原始哈希 ID 是最低级别的方式:哈希 ID 始终有效并且始终意味着一个特定的提交,但您也可以让 Git 找到某个提交的级。这就是HEAD^意思:选择当前提交的父级。假设当前提交是G因为你在branch;然后HEAD^命名 commit F,然后:

git checkout HEAD^

你将会有:

...--A--B--C--D   <-- master
         \
          E--F   <-- HEAD
              \
               G   <-- branch

小写版本head适用于 Windows 和 MacOS,但不适用于 Linux。这是 Git 有时将这些东西存储在文件中的副作用(例如.git/HEAD,和.git/refs/heads/master)。使用head而不是HEAD,Git 可能会尝试打开.git/refs/heads/head不存在的,但是当 Git 尝试打开时.git/head,它会得到.git/HEAD,它确实存在。所以在这些机器上git checkout head^意思是一样的git checkout HEAD^:找到当前的提交,回到它的第一个父节点,然后检查那个提交。

要将您重新附加HEAD到某个分支,请使用.git checkout branch-name

如果您不在 Windows 或MacOS上(或者即使您在),请注意您也可以创建一个名为. 如果你这样做了,事情会变得有点奇怪,尤其是在 Windows 和 MacOS 上,因为现在有两种解决方法:作为分支或标记,以及作为. 最好不要这样做。headhead.git/HEAD

于 2019-05-01T17:07:02.363 回答