open atlas
↑ К треку
Git: от нуля до сеньора GIT · 07 · 03

Теги и релизы

Теги именуют фиксированную точку истории, обычно релиз. Лёгкий тег — просто указатель; аннотированный тег (git tag -a) — настоящий объект с автором, датой и сообщением — используй его для релизов. Теги НЕ пушатся по умолчанию; отправляй их через git push --tags.

GIT Middle ◷ 15 min
Уровень
ОсновыJuniorMiddleSenior

Через шесть недель после релиза клиент сообщает о баге «в версии 1.4.0». Какой коммит был 1.4.0? Ветки двигаются, и main теперь на сотни коммитов впереди, поэтому тебе нужна постоянная именованная закладка на точном коммите, который ты выпустил. Эта закладка — тег — и правильно выбрать его тип и push означает разницу между чистым процессом релиза и запутанным.

К концу этого урока ты сможешь пометить релиз правильно, понять, почему аннотированные теги лучше лёгких для релизов, осознанно пушить теги и читать номер версии как инженер.

Цель

После этого урока ты сможешь создавать лёгкие и аннотированные теги, выбирать правильный для релиза, пушить теги на удалённый сервер (зная, что автоматически они не пушатся), осматривать тег и объяснять, что сообщает номер семантической версии.

1

Тег — это имя, постоянно прикреплённое к одному коммиту, обычно к точке релиза. В отличие от ветки, тег не двигается, когда ты добавляешь новые коммиты; он остаётся приколотым к коммиту, который пометил. Смотреть и осматривать теги:

git tag                 # перечислить все теги
git tag -l "v1.4.*"     # перечислить теги по шаблону
git show v1.4.0         # показать, на что указывает тег

Это даёт стабильный словарь: «баг в v1.4.0» навсегда отображается на один точный коммит, как бы далеко ни ушёл main.

2

Есть два вида тегов, и разница важна для релизов. Лёгкий тег — это просто имя, указывающее на коммит, и ничего больше. Аннотированный тег — это полноценный объект в базе git, хранящий имя автора тега, email, дату и сообщение (и может быть подписан GPG):

git tag v1.4.0-tmp                       # лёгкий: голый указатель, без метаданных
git tag -a v1.4.0 -m "Релиз 1.4.0"       # аннотированный: настоящий объект с автором + датой + сообщением

Используй лёгкие теги для приватных одноразовых закладок. Используй аннотированные теги для всего, что выпускаешь, потому что метаданные — кто нарезал релиз, когда, и сообщение — это ровно то, на что позже опирается аудит или git describe.

3

Теги НЕ пушатся по умолчанию — их надо отправлять явно. Обычный git push двигает коммиты веток, но оставляет твои новые теги лежать локально. Два способа их опубликовать:

git push origin v1.4.0     # запушить один конкретный тег
git push origin --tags     # запушить ВСЕ локальные теги, которых ещё нет на сервере

На этом спотыкаются почти все хотя бы раз: ты помечаешь релиз, пушишь, анонсируешь — а тега нигде нет на сервере, потому что ты его так и не отправил. Когда автоматизация (CI-пайплайны релиза) следит за тегами, забытый --tags молча пропускает твою релизную сборку.

4

Номера версий не произвольны: семантическое версионирование кодирует совместимость. Строка semver — это MAJOR.MINOR.PATCH, и у каждой части есть контракт:

v 1   .   4   .   2
  │       │       └─ PATCH: обратносовместимые исправления багов
  │       └───────── MINOR: новые функции, всё ещё обратносовместимо
  └───────────────── MAJOR: ломающие изменения (потребители должны адаптироваться)

Поднятие MAJOR сигналит «я сломал API»; MINOR говорит «новые функции, твой код всё ещё работает»; PATCH говорит «только исправления багов». Это язык, на котором твои теги говорят со всеми ниже по течению, поэтому имя тега несёт реальный смысл, а не просто ярлык.

Граничные случаи

Checkout тега даёт отсоединённый HEAD. Поскольку тег — не ветка, git checkout v1.4.0 высаживает тебя на коммит без прикреплённой ветки — HEAD указывает прямо на коммит. Это нормально для осмотра или сборки старого релиза, но любые коммиты, сделанные там, не принадлежат никакой ветке и могут быть потеряны. Если нужно что-то починить, начиная с тега, ответвись от него явно: git switch -c hotfix/1.4.1 v1.4.0.

Разбор примера

Нарезка и публикация релиза.

Тесты зелёные на main, и ты выпускаешь 2.0.0 — релиз, который выкидывает устаревший эндпоинт, так что это ломающее (MAJOR) изменение.

git switch main
git pull
git tag -a v2.0.0 -m "Релиз 2.0.0: удаление устаревшего /v1 API"
git show v2.0.0          # подтвердить автора, дату, сообщение и целевой коммит
git push origin v2.0.0   # опубликовать тег, чтобы CI и потребители его увидели

Аннотированный тег записывает, кто нарезал 2.0.0 и когда, номер 2.0.0 говорит каждому потребителю ожидать ломающих изменений, а явный push делает тег видимым на сервере, чтобы релизный пайплайн сработал. Коллега, чинящий его позже, выполняет git switch -c hotfix/2.0.1 v2.0.0, а не коммитит на отсоединённом HEAD.

Частая ошибка

Две повторяющиеся ошибки релизного дня: использование лёгкого тега для настоящего релиза (так что нет записи, кто и когда выпустил), и забывание, что теги не пушатся по умолчанию (так что тег есть на ноутбуке, но никогда не доходит до сервера или CI). Сделай связку аннотированный-тег-плюс-явный-push своим фиксированным ритуалом. Поднятие не той части semver — выпуск ломающего изменения как PATCH — это третья ошибка: она тихо ломает всех, кто доверял номеру в значении «безопасное обновление».

Проверь себя
Викторина

Ты выполнил git tag -a v3.0.0 -m 'Релиз 3.0.0', затем git push. Коллега говорит, что не видит тег на сервере. Почему?

Итог

Тег — это постоянное имя на одном коммите, используемое для пометки релизов. Лёгкий тег — голый указатель; аннотированный тег (git tag -a -m) — настоящий объект, хранящий автора, дату и сообщение — используй аннотированный для всего, что выпускаешь, и git tag -s, чтобы подписать его. Теги не пушатся по умолчанию: публикуй их через git push origin <tag> или --tags, иначе твой релиз останется невидимым для сервера и CI. Версионируй по semver (MAJOR.MINOR.PATCH), чтобы сам номер сообщал совместимость, и помни, что checkout тега даёт отсоединённый HEAD — ответвись от него, чтобы вносить правки. Дальше ты будешь запускать два рабочих дерева из одного репозитория с помощью git worktree.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.