7

Пытаясь настроить мое новое приглашение fish shell , я закончил тестировать способы получения имени ветви, а также проверял, был ли я в git-репозитории. Я нашел (1) git rev-parse --abbrev-ref HEAD , (2) git symbolic-ref HEAD | sed 's/refs\/heads\///' и (3) git describe --contains --all HEAD .

Мне любопытно, потому что я люблю простоту (1), но в новом и нетронутом (просто git init ed) репозитории он дает мне «роковую» ошибку, в то время как (2) работает так, как задумано, т.е. мне мастер по умолчанию в качестве вывода. Дело в том, что даже с ошибкой «fatal:» код возврата равен 0. Это предполагаемое поведение?

Чтобы проверить, был ли я в git-репозитории, я просто протестировал, есть ли в текущем каталоге папка «.git»: test -d ".git" . Простое решение, но оно работает, и кажется, что это быстрее, чем при использовании любой команды git.

Итак, мои вопросы:

  1. Разве этот «fatal:» с (1) не должен возвращать код выхода, отличный от 0? Если это действительно ошибка, так как я не знаю, как мерзавцы стандартизировали свои коды возврата, где я должен сообщить об этом?
  2. Я знаю, что если я перенаправлю (1) с помощью ^ /dev/null (для тех, кто не знает, ^ то же самое, что и 2>), я не получу сообщение об ошибке, но вместо «master» будет сказано « HEAD , но если я cat .git/HEAD , я получаю: ref: refs/heads/master . Что это должно сказать? С master я просто невежественен и придирчив, потому что вместо этого следует сказать HEAD? Я имею в виду только git init ed хранилище.
  3. Вы на самом деле тестировали возможные решения во время поисков, чтобы получить хорошую подсказку?

Вот код, который я использую для сравнения (для рыбы):

set -l before (date +%s%N)
git rev-parse --abbrev-ref HEAD
set -l after (date +%s%N)
set -l elapsed_time (expr $after - $before)
echo $elapsed_time

Заранее спасибо!

PS: это последние версии GNU, я имею в виду sed , date и expr . Извините, если информации слишком много или что-то не имеет смысла. Потерпите меня. Спасибо!

РЕДАКТИРОВАТЬ: Как кто-то правильно угадал в ответе, вся ошибка такова:

fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

1 ответ1

4

Не полностью отвечает на ваши вопросы, но, вероятно, немного больше, чем просто комментарий:

  1. Основываясь на других комментариях в вашем ответе, я думаю, что ошибка, которую вы увидели, является fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree. Это происходит потому, что вы проводите эти тесты в новом git-репозитории, в котором нет преданной работы. Мало того, что это не совсем честный тест (ваша производительность по определению будет хуже в большом хранилище), это почти во всех отношениях крайний случай. Например, .git/HEAD показывает ref: refs/heads/master по соглашению. Ошибка выдается, потому что HEAD неоднозначен. У вас нет истории, поэтому любое значение, переданное в rev-parse , будет обрабатываться одинаково. Кроме того, это не выходит 0 для меня:

    $ git init /tmp/test && cd /tmp/test
    $ git rev-parse --abbrev-ref HEAD
    $ echo $?
    128
    

    В общем, не переживайте эту ошибку. Возьмите один из огромных репозиториев Android или ядро Linux, и проверьте свою подсказку там.

  2. HEAD не ветка. Это указатель на извлеченное состояние. Когда вы отметили ветку, это символическая ссылка на эту ветку. Когда вы находитесь в состоянии «отделенный HEAD», указатель HEAD указывает на коммит. Вы получаете HEAD в качестве возврата, используя метод (1), потому что rev-parse просто повторяет переданное значение refspec в ошибке. Попробуйте это с blah ; вы увидите то же самое.

  3. На самом деле я не тестировал решения, но несколько вещей, которые вы могли бы попробовать (оба используются в моем приглашении zsh, которое я не писал, и оба работали довольно хорошо):

    git rev-parse --is-inside-work-tree ;# avoids your 'test -d .git' call
    ref=$(git symbolic-ref HEAD 2> /dev/null) ;# grab the full refspec
    branch=$(echo ${ref#refs/heads/}) ;# extract the branch name
    

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .