NodeGit 签出一个分支,但出现错误“HEAD 在原点/分支分离”?

问题描述

我正在使用 nodegit 从克隆结帐并打开它以执行某些操作。 我的代码是这样的:

//repo is a Repository from Clone() or open()
//branchName is your branch name,of course
repo.getBranch('refs/remotes/origin/' + branchName)
    .then(function(reference) {
        //checkout branch
        return repo.checkoutRef(reference);
    });

但之后我进入分支目录并输入这样的命令

git status
or git branch

像这样显示一条红线

HEAD detached at origin/branchname

我该如何解决? 谢谢

解决方法

一般来说,1origin/somebranch 不是 branch 名称,因此 git checkout origin/somebranch 会导致分离的 HEAD,正如您所看到的.

分支名称,在 Git 中,对于第一次近似来说,并没有什么好处。2 所以没有必要使用它们。要了解如何以及为什么会出现这种情况,让我们注意在 Git 中,有多种名称

分支机构名称 只是一个名称,在完整拼写时,以 refs/heads/ 开头。例如,分支名称 mastermain 实际上是 refs/heads/masterrefs/heads/main

标签名称是一个以refs/tags/开头的名称,在完整拼写时。所以 v2.1 真的是 refs/tags/v2.1

Git 称这些东西——这些名称的总称,在它们被分成某些特定的分类之前——refsreferences。每个引用保存一 (1) 个哈希 ID。哈希 ID 对 Git 来说真正重要。这就是 Git需要。这就是 git checkout 所需要的:哈希 ID。你可以给它任何有效的提交哈希 ID,它会检查那个提交。

但是,

哈希 ID 又大又丑,并且看起来是随机的(尽管它们不是)。它们完全令人难忘。无论如何,225365fb5195e804274ab569ac3cc4919451dc7f 是什么提交?如果我说v2.31.0-rc0,那对你来说可能意味着什么——或者至少,似乎暗示了什么;但如果我说 2253blah,您可能在我讲 2253 部分之前很久就忘记了 dc7f 部分。所以refs是给人类的。它们不是用于 Git,它只真正关心哈希 ID。

如果您是人类,则只需要一个引用(例如分支名称)。如果你是一个构建系统,哈希 ID 就可以了。如果您正在编写构建系统的一部分,只需使用哈希 ID。如果你正在写一些供人类使用的东西......好吧,人类是困难

Git 有一个特殊的东西,它叫做“DWIM”,或者 Do What I Mean,模式。如果你运行:

git checkout foobranch

并且现在没有名为 foobranch 的分支,Git 会假设您的意思是:给我找一个 相似的名字 {{1 }},例如foobranch。然后使用该名称为我制作一个分支名称。您可以使用 origin/foobranch 禁用它,有时这是一个好主意。但有时这种 DWIM 模式正是您想要的。

但是请注意,如果讨厌的人早点去制造他自己的 git checkout --no-guess,与foobranch无关,这个origin/foobranch将获得his git checkout foobranch,与 foobranch 无关。所以要小心:人类既狡猾又古怪。他们做了不合逻辑的、出乎意料的事情。

现在,人们经常想要使用 branch 名称是有原因的,而不是导致分离头模式的任何其他名称。他们喜欢这样的主要原因是,如果他们进行提交,Git 将更改存储在分支名称中的哈希 ID。新提交将自动向后链接到存储在引用中的任何提交。然后 Git 将更新分支名称,以便它现在存储提交的哈希 ID。

此功能专用于分支名称。没有其他类型的名称具有这种特殊功能。您可以在使用分支名称时选择 detached-HEAD 模式,例如通过运行 origin/foobranch。但是默认是当您使用带有分支名称的git checkout --detach foobranch时——即使是 DWIM 模式必须创建 —Git 将进入附加 HEAD 模式。3 所以这就是为什么人们喜欢分支名称,这就是 Git 对它们所做的,它不与任何其他参考名称。

如果您需要容纳人类,您可以通过让 DWIM 模式在此处发挥作用来实现。这不会让所有人满意,所以要小心。在某些情况下它也不起作用,所以要小心。不过,分离头模式始终有效。

In NodeGit specifically,you have Branch.create as an async class method of Branch.。你还有Branch.lookup。您可以使用它来查找远程跟踪名称,例如 git checkout,并使用它来创建新的本地分支(如果这是您的目标)。但和以前一样,请注意所有这些不同的边缘情况。


1可以创建一个名为 origin/branchname 的(本地)分支,因此它一个分支名称。除非您使用完整的拼写仔细地说出所有名称,否则结果会非常混乱。不要这样做!

2当然,他们确实做得很好,所以第一个近似值非常粗略。

3Git 并没有这样称呼它,但是“与分离的 HEAD 相反”模式的正确短语是什么?