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

Как я могу это решить? Спасибо

1 ответ

В общем случае 1 не является именем ветки , и поэтому git checkout origin/somebranchприводит к отсоединенной ГОЛОВКЕ, точно так же, как вы видите.

Имена веток в Git в первом приближении не приносят никакой пользы. 2 Так что нет необходимости их использовать. Чтобы понять, как и почему это так, отметим, что в Git есть много видов имен .

Имя ветки — это просто имя, которое при полном написании начинается с refs/heads/. Имена филиалов masterили же main, например, действительно refs/heads/masterа также refs/heads/main, соответственно.

Имя тега — это имя, которое при полном написании начинается с refs/tags/. Так v2.1действительно refs/tags/v2.1.

Git называет эти вещи — эти имена в целом, прежде чем они будут разделены на какую-то конкретную классификацию — refs или references . Каждая ссылка содержит один (1) хэш-идентификатор. Идентификатор хеша — это то, что действительно важно для Git. Это то, что нужно Git . Вот что требуется: хэш-идентификатор. Вы можете дать ему любой действительный хэш-идентификатор коммита, и он проверит этот коммит.

Однако хэш-идентификаторы большие и уродливые и выглядят случайными (хотя это не так). Они совершенно незапоминающиеся. Что такое коммит 225365fb5195e804274ab569ac3cc4919451dc7fтем не мение? Если я скажу v2.31.0-rc0, это, вероятно, что-то значит — или, по крайней мере, на что-то намекает — для вас; но если я скажу 2253blahвы, наверное, забыли 2253часть задолго до того, как я доберусь до dc7fчасть. Итак , рефы для людей . Они не для Git, который действительно заботится только о хэш-идентификаторах.

Вам нужна ссылка, например, название ветки, только если вы человек. Если вы система сборки, хэш-идентификатор подойдет. Если вы пишете часть системы сборки, просто используйте хэш-идентификатор. Если вы пишете что-то для человека... что ж, люди сложны .

У Git есть особая вещь, которую он называет «DWIM» или режим «Делай, что я имею в виду». Если вы запустите:

      git checkout foobranch

и в данный момент нет названной ветки , Git предположит, что вы имеете в виду: Найдите мне имя, похожее на , например . Затем используйте это имя, чтобы сделать для меня имя ветки. Вы можете отключить это с помощью git checkout --no-guessа иногда это хорошая идея. Но иногда этот режим DWIM — это именно то, что вам нужно.

Обратите внимание, однако, что если надоедливый человек пошел и сделал свой собственный ранее, не связанный с , это git checkout foobranchполучит свое foobranch, не связанный с origin/foobranch. Так что будьте осторожны: люди хитры и странны. Они делают нелогичные, неожиданные вещи.

Теперь есть причина, по которой люди часто хотят использовать имя ветки , а не любое другое имя, которое приводит к режиму detached-HEAD. Основная причина, по которой им это нравится, заключается в том, что тогда, если они сделают новый коммит, Git изменит хэш-идентификатор, хранящийся в названии ветки . Новый коммит автоматически свяжется в обратном направлении с любым коммитом , сохраненным в ссылке. Затем Git обновит имя ветки , чтобы теперь он хранил хэш-идентификатор нового коммита.

Эта функция является эксклюзивной для имен ветвей . Никакое другое имя не имеет этой особенности. Вы можете выбрать режим detached-HEAD при использовании имени ветки, запустив git checkout --detach foobranchнапример. Но по умолчанию , когда вы используете git checkoutс именем ветки — даже той, которую должен будет создать режим DWIM — вместо этого Git перейдет в режим прикрепленного HEAD . 3 Вот почему людям нравятся имена веток, и именно это Git делает с ними, чего он не делает ни с каким другим ссылочным именем.

Если вам нужно приспособиться к людям, вы можете сделать это, позволив режиму DWIM сделать здесь свое дело. Это не удовлетворит всех людей, так что берегитесь. В некоторых случаях это также не сработает, так что будьте осторожны. Однако режим detached-HEAD работает всегда.

В частности, в NodeGit у вас есть Branch.createкак асинхронный метод класса Branch.. У вас также естьBranch.lookup. Вы можете использовать это для поиска имени удаленного отслеживания, например origin/branchnameи используйте его для создания новой локальной ветки, если это ваша цель. Но, как и прежде, следите за всеми этими различными крайними случаями.


1 Можно создать (локальную) ветку с именем origin/somebranch, так что это имя ветки. Результат будет очень запутанным, если вы не будете тщательно называть все имена, используя их полное написание. Не делай этого!

2 Конечно, они приносят пользу, так что первое приближение довольно грубое.

3 Git не называет это так, но какой еще может быть правильная фраза для режима «напротив отсоединенного HEAD»?

Другие вопросы по тегам