Как получить имя текущей ветки в libgit2?

Я пытаюсь использовать libgit2 для чтения имени текущей ветки. Должен ли я принять какое-то решение?

я пытался использовать

git_branch_lookup

искать git_reference для HEAD, но это приводит к

Unable to find local branch 'HEAD'

Спасибо!


person Jake    schedule 26.08.2012    source источник


Ответы (3)


Запуск git branch -a не содержит HEAD. В libgit2 HEAD также не считается допустимой ветвью. Это всего лишь ссылка.

Если вы хотите узнать, какая ссылка является текущей ветвью, вам следует

  • Загрузите текущую ссылку HEAD (попробуйте удобный метод git_repository_head())
  • Определите его тип (используя git_reference_type())
  • Depending on its type (GIT_REF_SYMBOLIC or GIT_REF_OID) retrieve one of the following
    • The name of the branch (using git_reference_symbolic_target())
    • Коммит, на который указывает (используя git_reference_target())
person nulltoken    schedule 26.08.2012
comment
@ Джейк Был ли этот ответ полезен? - person nulltoken; 29.08.2012
comment
обратите внимание, что где-то после 0.0.17 libgit2 переименовал множество методов, включая методы git_reference_*: librelist.com/browser//libgit2/2012/11/28/ - person Nelson; 08.04.2013
comment
@Нельсон Спасибо. Это было исправлено. Ваше здоровье ;-) - person nulltoken; 08.04.2013
comment
Вам больше не нужно проверять тип ссылки, так как git_reference_resolve() разрешает прямые ссылки и фактически разрешает символические ссылки. - person T0xicCode; 09.04.2013
comment
@ xav0989 xav0989 Помните, что эти функции служат разным целям: git_reference_resolve будет очищать ссылку до тех пор, пока не будет найдена прямая ссылка, а затем вернет свой oid. git_reference_resolve принимает либо прямую, либо символическую ссылку. git_reference_target примет только прямую ссылку. git_reference_symbolic_target примет только символическую ссылку в качестве входных данных и вернет имя ссылки, на которую указывает (которая может быть прямой или другой связанной символической ссылкой). - person nulltoken; 09.04.2013
comment
@nulltoken Да. Я предположил, что oid коммита, в конечном итоге связанный с этой ссылкой, был конечной целью, но если следующей целью является конечная цель, лучше подходят функции git_reference-*target. - person T0xicCode; 09.04.2013

Я не нашел существующий ответ/комментарий полезным, когда возникла именно эта проблема. Вместо этого я объединил git_reference_lookup() и git_reference_symbolic_target().

git_reference* head_ref;
git_reference_lookup(&head_ref, repo, "HEAD");
const char *symbolic_ref;
symbolic_ref = git_reference_symbolic_target(head_ref);
std::string result;
// Skip leading "refs/heads/" -- 11 chars.
if (symbolic_ref) result = &symbolic_ref[11];
git_reference_free(head_ref);

Это похоже на какой-то грязный взлом, но это лучшее, что мне удалось. Строка result либо заканчивается пустой (например, отсоединенная голова, нет проверенной ветки), либо содержит имя извлеченной ветки. Символическая цель принадлежит ссылке, поэтому скопируйте это значение в строку перед ее освобождением!

person arantius    schedule 21.01.2021
comment
Оглядываясь назад, это почти то же самое, что сказал существующий ответ, просто он также содержит некоторые (устаревшие?) отвлекающие маневры, которые сначала меня смутили. - person arantius; 21.01.2021

Пример для этого есть на странице https://libgit2.org/libgit2/ex/HEAD/status.html . Он основан на методе get_reference_shorthand. Это должно дать имя ветки вместо ссылки, поэтому манипуляции со строками не требуются, и это также должно работать в пограничном случае, когда ветка и удаленный имеют разные имена.

static void show_branch(git_repository *repo, int format)
{
  int error = 0;
  const char *branch = NULL;
  git_reference *head = NULL;

  error = git_repository_head(&head, repo);

  if (error == GIT_EUNBORNBRANCH || error == GIT_ENOTFOUND)
    branch = NULL;
  else if (!error) {
    branch = git_reference_shorthand(head);
  } else
    check_lg2(error, "failed to get current branch", NULL);

  if (format == FORMAT_LONG)
    printf("# On branch %s\n",
      branch ? branch : "Not currently on any branch.");
  else
    printf("## %s\n", branch ? branch : "HEAD (no branch)");

  git_reference_free(head);
}
person Kjell    schedule 31.01.2021