Выключить ветвь/тег с нодегитом

Я пытаюсь все утро открывать существующее репо и менять ветку или тег, используя nodegit. Документация обширна, но, похоже, устарела. Любые идеи о том, что я делаю неправильно?

var NodeGit = require("nodegit");
var open = NodeGit.Repository.open;
var Tag = NodeGit.Tag;
var Checkout = NodeGit.Checkout;

open(location).then(function (repo) {
    Tag.list(repo).then(function(array) {
        // array is ['v1.0.0']
        var ref = array[0]
        Checkout.tree(repo, ref).then(function() {
            // Want tag to be checked out out in detached state.
        });
    });
});

Ответ 1

Таким образом, есть несколько вещей, которые вам не хватает в коде. Во-первых, вы не прекращаете цепочку обещаний, поэтому проглатываются ошибки. Вы хотите закончить его либо с помощью .catch, либо .done.

Во-вторых, я думаю, вы не совсем уверены, что делает проверка. Одна из запутанных вещей с низким уровнем git и то, как она отличается от CLI git, заключается в том, что Checkout только обновляет ваш рабочий каталог, чтобы отразить дерево, на которое указывает второй параметр.

В-третьих, вы передаете строку методу, ожидающему чего-то еще. Документы показывают, что он ищет Oid, Tree, Commit или Reference. Немного вернем этот код.

var NodeGit = require("nodegit");
var open = NodeGit.Repository.open;
var Tag = NodeGit.Tag;
var Checkout = NodeGit.Checkout;

open(location).then(function (repo) {
  return Tag.list(repo)
    .then(function(array) {
      // array is ['v1.0.0','v2.0.0']
      return Tag.lookup(repo,array[0]);
    })
    .then(function(tag) {
      return Checkout.tree(repo, tag.targetId(), { checkoutStrategy: Checkout.STRATEGY.SAFE_CREATE})
        .then(function() {
          repo.setHeadDetached(tag.targetId(), repo.defaultSignature, "Checkout: HEAD " + tag.targetId());
        });
     });
})
.catch(function(error) {
  // log error
});

Это должно указывать вам в правильном направлении. Если вам нужна дополнительная помощь, я бы рекомендовал остановить наш канал gitter, где мы довольно активны.

Ответ 2

Следующее полное решение работает для меня для тегов, которые могут быть либо легкими, либо аннотированными тегами: (repo - открытый репозиторий, tag - это имя тега для проверки)

var Git = require("nodegit"); 

function checkOutTag(repo, tag) {
    return Git.Reference
      .dwim(repo, "refs/tags/" + tag)
      .then(function (ref) {
          return ref.peel(Git.Object.TYPE.COMMIT);
      })
      .then(function (ref) {
          return repo.getCommit(ref);
      })
      .then(function (commit) {
          return Git.Checkout
            .tree(repo, commit, {checkoutStrategy: Git.Checkout.STRATEGY.SAFE})
            .then(function () {
                return repo.setHeadDetached(commit, repo.defaultSignature, 
                                            "Checkout: HEAD " + commit.id());
          })
    });
 }

Это может быть проще с помощью repo.getReferenceCommit(), но эта команда в настоящее время терпит неудачу для аннотированных тегов. См. Также https://github.com/nodegit/nodegit/issues/1370, который отслеживает эту проблему.