В чем разница между аннотированным и аннотированным тегом?

Если я хочу пометить текущий коммит. Я знаю, что обе следующие командные строки работают:

git tag <tagname>

а также

git tag -a <tagname> -m '<message>'

В чем разница между этими командами?

4 ответа

TL;DR

Разница между командами заключается в том, что одна предоставляет вам сообщение тега, а другая - нет. У аннотированного тега есть сообщение, которое можно отобразить с помощью git-show(1), а тег без аннотаций - это просто именованный указатель на коммит.

Подробнее о легких тегах

Согласно документации: "Чтобы создать легкий тег, не указывайте ни один из параметров -a, -s или -m, просто укажите имя тега". Есть также несколько вариантов написания сообщения для аннотированных тегов:

  • Когда вы используете git tag <tagname>, Git создаст тег в текущей ревизии, но не будет запрашивать аннотацию. Он будет помечен без сообщения (это облегченный тег).
  • Когда вы используете git tag -a <tagname>, Git предложит вам аннотацию, если вы не использовали флаг -m для предоставления сообщения.
  • Когда вы используете git tag -a -m <msg> <tagname>, Git пометит коммит и аннотирует его предоставленным сообщением.
  • Когда вы используете git tag -m <msg> <tagname>, Git будет вести себя так, как будто вы передали флаг -a для аннотации и используете предоставленное сообщение.

По сути, это просто означает, хотите ли вы, чтобы у тега была аннотация и некоторая другая информация, связанная с ним, или нет.

Нажмите аннотированные метки, сохраняйте вес локальным

man git-tag говорит:

Аннотированные теги предназначены для выпуска, в то время как легкие теги предназначены для меток частных или временных объектов.

И некоторые виды поведения делают различие между ними таким образом, что эта рекомендация полезна, например:

  • аннотированные теги могут содержать сообщение, создателя и дату, отличную от фиксации, на которую они указывают. Таким образом, вы можете использовать их для описания релиза, не делая релиз релиза.

    Облегченные теги не имеют такой дополнительной информации и не нуждаются в ней, поскольку вы будете использовать ее только для разработки.

  • git push --follow-tags будет толкать только аннотированные теги
  • git describe без параметров командной строки видит только аннотированные теги

Внутренние различия

  • как легкие, так и аннотированные теги являются файлом под .git/refs/tags который содержит SHA-1

  • для легких тегов SHA-1 указывает непосредственно на коммит:

    git tag light
    cat .git/refs/tags/light
    

    печатает так же, как SHA-1 ГОЛОВКИ.

    Поэтому неудивительно, что они не могут содержать никаких других метаданных.

  • аннотированные теги указывают на объект тега в базе данных объекта.

    git tag -as -m msg annot
    cat .git/refs/tags/annot
    

    содержит SHA аннотированного тегового объекта:

    c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef
    

    и тогда мы можем получить его содержание с:

    git cat-file -p c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef
    

    образец вывода:

    object 4284c41353e51a07e4ed4192ad2e9eaada9c059f
    type commit
    tag annot
    tagger Ciro Santilli <your@mail.com> 1411478848 +0200
    
    msg
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.11 (GNU/Linux)
    
    <YOUR PGP SIGNATURE>
    -----END PGP SIGNAT
    

    И вот как он содержит дополнительные метаданные. Как мы видим из вывода, поля метаданных:

    Более подробный анализ формата представлен по адресу: Что такое формат объекта тега git и как рассчитать его SHA?

Бонусы

Большая разница прекрасно объясняется здесь.

По сути, легкие теги являются просто указателями на конкретные коммиты. Дальнейшая информация не сохраняется; с другой стороны, аннотированные теги являются обычными объектами, которые имеют автора и дату, и на них можно ссылаться, поскольку они имеют свой собственный ключ SHA.

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

Обычно вы бы использовали аннотированные теги, но это действительно зависит от мастера Git проекта.

Еще одно отличие заключается в случае сбоя, поскольку тег уже есть, как .

С Git 2.42 (3 квартал 2023 г.): " « ( мужчина ) научился выходить из"$GIT_DIR/TAG_EDITMSG"файл в случае сбоя команды, чтобы пользователь мог восстановить то, что он набрал.
Этот файл сообщения тега git не будет существовать для облегченного тега.

См. , коммит 669c11d , (16 мая 2023 г.) Кристоффера Хаугсбакка ( LemmingAvalanche) .
(Объединено Джунио К. Хамано -- gitster-- в коммите 6d2a88c, 13 июня 2023 г.)

коммит 08c12ec: сохранить файл сообщений на случай сбоя ref-транзакции

Подпись: Кристоффер Хаугсбакк

Ссылочная транзакция может завершиться неудачно после того, как пользователь записал свое сообщение тега.
В частности, если существует тегfoo/barи git tag -a foo( человек ) говорит, что команда завершится неудачно только тогда, когда она попытается записатьrefs/tags/foo, то есть после того, как файл был отключен.

Подержите файл сообщения еще немного, чтобы он не был отсоединен до того, как произойдет фатальная ошибка.

И:

коммит 719515fdoc: тег: документ

Предложено: Джунио К. Хамано
Подпись: Кристоффер Хаугсбакк

Документ, о котором мы сообщали пользователю при неудачном вызове команды после ("tag: удалитьTAG_EDITMSGтолько при успешном теге", 6 декабря 2008 г., Git v1.6.1-rc2 -- merge).

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

Используйте документацию дляCOMMIT_EDITMSGотgit-commit.txtв качестве шаблона, поскольку эти два файла имеют одну и ту же цель. описано здесь1

† 1: из фиксации 3927bbeфиксации 3927bbe :

       “ This matches the behavior of COMMIT_EDITMSG, which stays around
  in case of error.

теперь включает в свою справочную страницу :

ФАЙЛЫ

$GIT_DIR/TAG_EDITMSG

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

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