Всем привет, меня зовут Сергей Прощаев. Я руковожу направлением Java‑разработки в FinTech, а ещё помогаю начинающим специалистам осваивать тонкости профессии на курсах Отус. Сегодня поговорим о Git. Точнее, о том, как перестать его бояться и начать использовать так, чтобы коллеги (и вы сами) не краснели, глядя на историю ваших изменений.

Почему я решил написать эту статью? На любом курсе по разработке в Отус есть блок вебинаров по работе с Git. И в большинстве случаев основная сложность начинается здесь. Ветки называются «asdasd», коммиты — «правки», «ы», «апдейт», а в пулл‑реквесте висит 50 файлов с изменениями, половина из которых — случайно попавший туда мусор. И самое грустное, что многие даже не понимают, в чём проблема. «Ну работает же, чего вы придираетесь?»

Но в реальной команде такой подход приведёт к хаосу. Представьте, что вам нужно откатить изменение, которое сломало тесты, а все коммиты подписаны «fix» — попробуй найди нужный. Или вы мержите ветку, а там конфликты, которые не распутать, потому что никто не заботился об актуальности своей ветки. Git — это не просто хранилище кода, это инструмент коммуникации. И сегодня я покажу, как сделать эту коммуникацию эффективной.

Git — это не страшно, это просто граф

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

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

Рис. 1 Пример графа коммитов в Git
Рис. 1 Пример графа коммитов в Git

На рисунке 1 изображен пример графа коммитов: на main сделан начальный коммит, от него отходит ветка feature/login, в ней два коммита, затем на main добавлен ещё один коммит (исправление опечатки) и выполнено слияние feature/login.

Здесь всё просто: main (или master) — основная ветка, с которой обычно работают пользователи. feature/login — ветка для разработки новой функциональности. После того как фича готова, её вливают обратно в main. Именно так выглядит изолированная работа: вы не мешаете другим, другие не мешают вам.

Какими бывают ветки

В учебных проектах или на небольших задачах часто хватает одной основной ветки и нескольких тематических. Но в серьёзной разработке сложились модели ветвления, самая известная из которых — Git Flow. Она предписывает иметь долгоживущие ветки main и develop, а также временные: feature/*release/*hotfix/*.

  • main — всегда содержит стабильный, готовый к выкладке код

  • develop — ветка интеграции, куда сливаются все новые фичи

  • feature/* — каждая новая функциональность разрабатывается в своей ветке от develop

  • release/* — подготовка к релизу (исправление багов, документация)

  • hotfix/* — срочные исправления на main

Звучит сложно, но на практике для новичка главное понять разницу между долгоживущей(main, develop) и временной веткой (ваша задача). Временная ветка живёт ровно столько, сколько вы делаете задачу. Как только её вмержили, ветку можно (и нужно) удалить — и локально, и на сервере.

На курсах «OTUS» мы обычно используем упрощённый вариант: есть main и от неё отходят ветки для домашних заданий с префиксом homework/. Например: homework/lesson1-git-basics. Это сразу говорит, что в ветке, и облегчает жизнь ментору.

Создаём ветку: от слов к делу

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

Допустим, вы клонировали репозиторий курса. Убедитесь, что вы находитесь на актуальном main:

git checkout main
git pull origin main

Теперь создаём новую ветку для своего задания. Рекомендую сразу переключиться на неё:

git checkout -b homework/lesson1-git-basics

Флаг -b создаёт ветку и переключает на неё. Если хотите сделать то же самое по шагам:

git branch homework/lesson1-git-basics   # создали ветку
git checkout homework/lesson1-git-basics # переключились

Современный Git (версии 2.23+) предлагает более понятные команды:

git switch -c homework/lesson1-git-basics

Как назвать ветку — вопрос договорённости в команде. Встречал разные стили: feature/JIRA-123, bugfix/issue-description, username/task-name.

Главные правила: никаких кириллицы и пробелов, используйте дефисы или слеши для разделения слов. Например: feature/add-user-service, hotfix/fix-npe, homework/03-junit-tests.

Коммиты: каждый шаг должен быть осмыслен

Итак, вы написали код для своего задания. Например, простой класс User:

package ru.otus;

public class User {
    private String name;
    private String email;

    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }

    // ...
}

Как сохранить изменения в Git? Сначала добавляем файлы в индекс (staging area):

git add src/main/java/ru/otus/User.java

Можно добавить все изменённые файлы сразу: 

git add . 

но будьте осторожны — так вы можете случайно захватить временные файлы или мусор. Лучше явно перечислить то, что должно попасть в коммит.

Теперь создаём коммит:

git commit -m "Add User class with name and email"

Но давайте остановимся и подумаем: хорошее ли это сообщение? Оно отвечает на вопрос «Что сделано?» — добавлен класс User. Но не отвечает на вопрос «Почему?». Если коммит маленький и очевидный, можно ограничиться одной строкой. Но представьте, что вы возвращаетесь к этому коду через полгода и видите сообщение «Add User class». Вы уже не вспомните, зачем понадобился этот класс и почему поля именно такие.

Поэтому в сообщениях коммитов придерживайтесь best practices:

  1. Заголовок (первая строка) — не длиннее 50 символов, пишется в повелительном наклонении («Add», «Fix», «Update»), без точки в конце. Это как тема письма.

  2. Если нужно больше деталей, после пустой строки идёт тело сообщения. В нём можно описать мотивацию изменений, ссылки на задачи, важные технические нюансы. Ширина строки тела — до 72 символов для удобства чтения в консоли.

  3. Хороший тон — привязывать коммит к задаче в трекере (например, JIRA-123: Add validation for email).

Пример хорошего сообщения (вводится через git commit без флага -m, чтобы открылся редактор):

Add User class for authentication module

- User stores name and email
- Email must be unique in the system (will be enforced by DB)
- This class is part of the new login flow described in #TASK-456

The previous implementation used a separate profile class, but we need
a single entry point for user data.

Есть и более формальный подход — Conventional Commits. Он предписывает использовать префиксы типа feat:, fix:, docs:, style:, refactor:, test:, chore:. Это особенно полезно, если вы потом автоматически генерируете changelog. Для домашнего задания это может быть избыточно, но на работе такой стиль часто входит в стандарт команды.

Основная идея: сообщение коммита начинается с префикса, который обозначает тип изменения, затем двоеточие и пробел, а после – краткое описание. Иногда можно добавить область (scope) в скобках после типа, например feat(api): add new endpoint.

Вот расшифровка самых частых префиксов и примеры к ним:

Префикс

Когда использовать

Пример сообщения

feat:

Добавление новой функциональности для пользователя (новая фича, новый модуль, новый метод в публичном API)

feat: add password recovery by email

fix:

Исправление ошибки (бага).

fix: handle division by zero in calculator

docs:

Изменения только в документации (README, Javadoc, комментарии в коде).

docs: update project setup guide

style:

Правки форматирования, отступов, лишних пробелов, точек с запятой – всё, что не меняет логику кода.

style: reformat code according to google style guide

refactor:

Изменение кода, которое не исправляет ошибку и не добавляет новую функциональность (например, переименование переменной, выделение метода).

refactor: extract email validation to separate method

test:

Добавление или изменение тестов (юнит-тесты, интеграционные тесты).

test: add negative scenarios for login

chore:

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

chore: update maven compiler plugin to 3.8.1

Эти префиксы – ядро, но есть и другие: perf: (улучшение производительности), ci:(изменения в CI/CD), build: (изменения в системе сборки), revert: (откат коммита). Для начала достаточно освоить основные семь.

Как это выглядит на практике?

Допустим, вы пишете домашнее задание и добавляете класс User. Логично сделать коммит типа feat. Но если вы потом заметили, что забыли обработать пустой email, и исправляете – это fix. А если просто перенесли метод в другой класс без изменения логики – refactor.

git commit -m "feat: add User class with name and email"
git commit -m "fix: validate email format in User constructor"
git commit -m "refactor: move email validation to EmailUtils"

Теперь, взглянув на историю, любой сразу поймёт, что происходило. А если подключить инструмент вроде standard-version, он на основе этих префиксов автоматически увеличит версию и сгенерирует красивый changelog.

Однажды потратил полдня, разбираясь, почему упал билд после мержа. Оказалось, коллега сделал коммит с сообщением «правки» и случайно удалил важную зависимость в pom.xml. Если бы он написал «Remove unused dependency», я бы даже не открывал тот коммит, потому что «unused» не должно ломать сборку. А так пришлось вручную перебирать все «правки». С тех пор я требую от команды осмысленных сообщений.

Pull Request: как показать результат

Вы сделали несколько коммитов в своей ветке, всё проверили локально. Теперь нужно отправить задание на проверку преподавателю. Для этого вы пушите ветку в удалённый репозиторий:

git push origin homework/lesson1-git-basics

Если ветки на сервере ещё нет, Git создаст её. Теперь идём на сайт GitHub (или GitLab, Bitbucket) и видим красивую кнопку «Create pull request», как показано на рисунке 2 и нажимаем.

Рис. 2 Кнопка создания Pull Request на GitHub
Рис. 2 Кнопка создания Pull Request на GitHub

Важно! Перед созданием PR убедитесь, что ваша ветка не отстала от основной. Пока вы писали код, в main могли добавиться новые коммиты. Если не подтянуть их, после мержа могут возникнуть конфликты. Поэтому я всегда делаю перед пушем:

git fetch origin
git rebase origin/main

Эта команда переставляет ваши коммиты поверх последних изменений в main. Если есть конфликты, вы решаете их локально, а не в PR. Это правило профессионалов.

Теперь заполняем описание PR. Оно должно быть информативным: что сделано, как проверить, есть ли особенности. Пример:

Название PR: Homework 1: Git basics (User class)
Описание:

  • Реализован класс User с полями name, email.

  • Добавлены тесты (если были).

  • Задание выполнено согласно требованиям: ...

Как проверить:

  1. Запустить тесты: mvn test

  2. Убедиться, что код компилируется.

В PR вы можете указать ревьюера (преподавателя), добавить метки, прикрепить скриншоты. Главное — не оставляйте описание пустым.

Что еще запомнить?

  • Перед коммитом всегда проверяй, что попадает в индекс (git status).

  • Не забывай про .gitignore — туда нужно добавить папки IDE, результаты сборки (target/, build/), логи.

  • Описание PR должно быть понятным, чтобы ревьюеру не приходилось гадать, что ты хотел сделать.

  • И главное: ревью — это не критика, а помощь. Комментарии преподавателя делают код лучше.

  • Git — это не просто команды, это культура разработки. 

Что дальше? Конфликты, rebase, работа в команде

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

На курсе «Автоматизация тестирования на Java. Базовый уровень» как раз разбирается база: Java, автотесты для интерфейса и API, ключевые шаблоны и инструменты, с которыми тестирование становится воспроизводимым и внятным. Для знакомства с форматом обучения и экспертами приходите на бесплатные уроки:

  • 19 марта, 20:00. «Основы многопоточности в Java. Асинхронные методы». Записаться

  • 23 марта, 20:00. «ИИ в автотестах: помощник или угроза?». Записаться

Полный список бесплатных уроков марта по всем ИТ-направлениям смотрите в дайджесте.