$ sudo teach IT
Модуль 7 · Чистая история · Урок 7.4

Практикум: релиз v1.0

Вы выпустите первую версию сайта: CHANGELOG.md, аннотированный тег v1.0.0 и релиз на GitHub.

Практикум~25 минутНовичокtagReleases

Задание

Тег в Git (tag) — это постоянная метка на коммите с понятным именем, например v1.0.0; а релиз на GitHub — страница этой версии с описанием изменений и архивом кода. Вы выпустите первую версию визитки: опишете изменения в CHANGELOG.md, поставите аннотированный тег v1.0.0 и опубликуете релиз на GitHub.

История проекта чистая, вы умеете искать по ней. Но в ней уже полсотни коммитов, и на вопрос «какую версию сайта вы показывали работодателю в ноябре?» хеш 3390e52 не ответит. Нужны имена для важных точек.

Тег и ветка

Простыми словами: ветка — закладка, которая сама переезжает на новую страницу, когда вы пишете дальше. Тег — надпись маркером на полях: она остаётся на своей странице навсегда. Поэтому тегами отмечают версии: v1.0.0 через год укажет на тот же самый коммит.

Теги бывают двух видов. Лёгкий (lightweight) — просто имя для коммита. Аннотированный (annotated, флаг -a) хранит ещё автора, дату и сообщение. Документация Git советует аннотированные для релизов, а лёгкие — для личных временных пометок.

Номер версии: MAJOR.MINOR.PATCH

Мы используем семантическое версионирование (Semantic Versioning, SemVer): три числа через точку, и каждое что-то значит.

ЧастьКогда увеличиватьПример для визитки
PATCH (третья)Исправили ошибку, ничего нового1.0.0 — 1.0.1: опечатка в тексте
MINOR (вторая)Добавили новое, старое работает как раньше1.0.1 — 1.1.0: новая страница «Заметки»
MAJOR (первая)Изменили так, что старое больше не работает как раньше1.1.0 — 2.0.0: сайт переделан, старые адреса страниц исчезли

При увеличении числа правые обнуляются: после 1.4.2 новая возможность даёт 1.5.0. Буква v в имени тега — привычная договорённость, сам номер версии — 1.0.0.

Разбор

Шаг 1. CHANGELOG.md

CHANGELOG.md — файл со списком изменений по версиям, написанный для людей. Не путайте его с git log: в логе каждый маленький коммит, а в CHANGELOG — то, что важно пользователю. Популярный формат Keep a Changelog: свежая версия сверху, заголовок ## [номер] - дата (дата в виде год-месяц-день), под ним разделы по типу изменений: Added (добавлено), Changed (изменено), Fixed (исправлено), а также Deprecated, Removed, Security. Пустые разделы не пишут.

main защищён правилом, поэтому даже CHANGELOG идёт через pull request:

Терминал
$ git switch main
$ git pull
$ git switch -c docs/changelog

Создайте в корне проекта файл. Дату поставьте сегодняшнюю, пункты поправьте под свой сайт:

Markdown · CHANGELOG.md
# Changelog

Здесь записаны все заметные изменения сайта-визитки.
Формат: Keep a Changelog, номера версий: Semantic Versioning.

## [1.0.0] - 2026-11-18

### Added
- Главная страница: «Обо мне», «Мои проекты», «Контакты».
- Страница проектов projects.html.
- Подвал с подписью «Сайт на GitHub Pages, сделано с помощью Git».
- Тёмная тема: сайт сам подстраивается под настройку системы.

### Fixed
- Ссылка «Все мои проекты» снова ведёт на projects.html.
Терминал
$ git add CHANGELOG.md
$ git commit -m "Добавить CHANGELOG"
[docs/changelog 24e7597] Добавить CHANGELOG
 1 file changed, 15 insertions(+)
 create mode 100644 CHANGELOG.md
$ git push -u origin docs/changelog

Создайте pull request, слейте его, затем у себя: git switch main, git pull, git branch -d docs/changelog. Убедитесь, что вы на последнем коммите:

Терминал
$ git log --oneline -2
3390e52 Merge pull request #10 from alex-ivanov/docs/changelog
24e7597 Добавить CHANGELOG

Шаг 2. Тег v1.0.0

Тег ставится на текущий коммит (или на указанный хешем после имени). Сообщение — как у коммита, через -m:

Терминал
$ git tag -a v1.0.0 -m "Первая версия сайта-визитки"
$ git tag
v1.0.0
$ git show v1.0.0
tag v1.0.0
Tagger: Алекс Иванов <alex@example.com>
Date:   Wed Nov 18 10:40:00 2026 +0300

Первая версия сайта-визитки

commit 3390e527c75028287de9dbc6619da79212094fc1
Merge: 138d90c 24e7597
Author: Алекс Иванов <alex@example.com>
Date:   Wed Nov 18 10:30:00 2026 +0300

    Merge pull request #10 from alex-ivanov/docs/changelog
...

Разбор по строкам

  • git tag -a v1.0.0 -m "..." — создать аннотированный тег на текущем коммите; при успехе Git ничего не печатает.
  • git tag — список всех тегов репозитория.
  • tag v1.0.0 / Tagger / Date — данные самого тега: кто и когда его поставил.
  • Первая версия сайта-визитки — сообщение тега.
  • commit 3390e52... — коммит, на который указывает тег: здесь это слияние pull request с CHANGELOG.
  • Merge: 138d90c 24e7597 — у merge-коммита два родителя: прежний конец main и коммит из ветки.

Тег виден и в истории: git log --oneline -1 покажет 3390e52 (HEAD -> main, tag: v1.0.0, origin/main) Merge pull request #10 ….

Шаг 3. Отправить тег

Частая путаница: обычный git push теги не отправляет. Отправить тег напрямую можно: правило «Защита main» касается только ветки main, на теги оно не действует.

Терминал
$ git push
Everything up-to-date
$ git push origin v1.0.0
To https://github.com/alex-ivanov/portfolio.git
 * [new tag]         v1.0.0 -> v1.0.0

Разбор по строкам

  • Everything up-to-date — «всё актуально»: ветки на GitHub совпадают с вашими, а про теги обычный push не думает.
  • git push origin v1.0.0 — отправить один тег по имени.
  • * [new tag] v1.0.0 -> v1.0.0 — на GitHub появился новый тег.

Есть и git push --follow-tags: вместе с ветками он отправит аннотированные теги на отправляемых коммитах. Подробно о тегах — git tag.

Шаг 4. Релиз на GitHub

Тег — это метка внутри Git. Релиз — страница на GitHub, которую видят все: описание версии и архивы с кодом. Порядок по документации GitHub:

  1. Откройте главную страницу репозитория alex-ivanov/portfolio (логин свой).
  2. Справа от списка файлов нажмите Releases (релизы).
  3. Вверху страницы нажмите Draft a new release (подготовить новый релиз).
  4. В списке Choose a tag (выбрать тег) выберите v1.0.0.
  5. В поле «Release title» (название релиза) напишите v1.0.0 — первая версия.
  6. В поле «Describe this release» (описание) вставьте раздел версии из CHANGELOG.md или нажмите Generate release notes — GitHub сам соберёт список слитых pull request, участников и ссылку на полный список изменений.
  7. Галочку This is a pre-release (предварительная версия) не ставьте: версия готовая.
  8. Нажмите Publish release (опубликовать). Не готовы — Save draft сохранит черновик.

На странице релиза появятся название, описание и архивы с кодом этой версии, а на главной репозитория справа — блок Releases с меткой последней версии. Подробно — Managing releases in a repository.

Шпаргалка модуля

КомандаЧто делает
git rebase mainПеренести коммиты своей ветки на конец main
git rebase --continue / --abortПродолжить после решения конфликта / отменить rebase
git push --force-with-leaseОтправить переписанную ветку, если на GitHub нет чужих новых коммитов
git cherry-pick <хеш>Скопировать один коммит в текущую ветку
git rebase -i mainПричесать коммиты ветки: pick, reword, squash, fixup, drop
git commit --fixup <хеш> + git rebase -i --autosquash mainИсправление к старому коммиту, которое само встанет на место
git log --author --since --grep -S -- файлФильтры истории
git blame файлКто и в каком коммите последним менял каждую строку
git bisect start / bad / good / resetБинарный поиск коммита с ошибкой
git tag -a v1.0.0 -m "…"Аннотированный тег на текущем коммите
git push origin v1.0.0Отправить тег на GitHub

Проверьте себя

  • В корне проекта есть CHANGELOG.md с разделом ## [1.0.0], и он есть в main на GitHub.
  • git tag печатает v1.0.0, а git show v1.0.0 начинается со строк tag v1.0.0 и Tagger: ….
  • git log --oneline -1 в main показывает tag: v1.0.0 рядом с последним коммитом.
  • На странице Releases вашего репозитория опубликован релиз v1.0.0 (не черновик).
  • git status пишет nothing to commit, working tree clean.

Частые ошибки

Поставили лёгкий тег вместо аннотированного. Забыли -a: git show v1.0.0 сразу начинается с commit …, без Tagger и сообщения. Пока тег не отправлен, удалите его и поставьте заново:

Терминал
$ git tag -d v1.0.0
Deleted tag 'v1.0.0' (was 3390e52)
$ git tag -a v1.0.0 -m "Первая версия сайта-визитки"

Поставили тег не на тот коммит. Например, забыли git pull и отметили коммит до слияния CHANGELOG. Перед тегом смотрите git log --oneline -1. Ещё не отправили — исправьте так же через git tag -d.

Тега нет в списке Choose a tag. Его не отправили: обычный git push теги не берёт. Выполните git push origin v1.0.0 и обновите страницу.

fatal: tag 'v1.0.0' already exists. Тег с таким именем уже есть. Имена тегов уникальны: проверьте git tag.

Опубликованный тег не переносят

Тег, который уже на GitHub и в релизе, двигать на другой коммит нельзя: кто-то уже скачал эту версию, и у него v1.0.0 будет означать другое, чем у вас. Нашли ошибку после релиза — исправьте её обычным путём и выпустите v1.0.1.

Что важно запомнить

  • Тег — постоянная метка на коммите; ветка движется, тег нет.
  • Для релизов — аннотированный тег: git tag -a v1.0.0 -m "…".
  • Версия MAJOR.MINOR.PATCH: исправление — PATCH, новое без поломки — MINOR, несовместимое — MAJOR.
  • Теги отправляют отдельно: git push origin v1.0.0.
  • CHANGELOG пишут для людей, релиз на GitHub — страница версии: Releases, Draft a new release, Publish release.
  • Опубликованный тег не переносят — выпускают следующую версию.

Модуль закончен: у вас чистая история, вы умеете её переписывать, искать по ней и отмечать версии. Остался последний шаг — провести изменение через весь цикл самостоятельно, от issue до релиза. Этим и займётся финальный проект: новая страница «Заметки», squash merge и версия v1.1.0.

На следующий урок