Разбираем фичи по кусочкам: атомарные коммиты как внутренняя дисциплина
Дима руководит группой прикладной разработки в Naumen и много лет работает с командами, которые делают не одноразовые фичи, а долгоживущие системы — те, что развиваются годами, переживают смену людей, требований и контекста.

В статье он рассказывает о декомпозиции: зачем она на самом деле нужна в разработке и какую неожиданную роль в этом играют атомарные коммиты.
Что такое декомпозиция и почему с неё всё начинается
Декомпозиция — это разбиение задачи на более мелкие подзадачи или шаги. Идея настолько очевидная, что часто кажется, будто обсуждать тут нечего. Но именно с этого шага начинаются осмысленные инженерные решения.
Например, у нас есть большая задача. Мы не пытаемся решить её целиком, а разбиваем на части и идем по ним последовательно. В этом смысле разработка мало отличается от любой другой сложной деятельности.
Зачем вообще декомпозировать задачи
Когда говорят о декомпозиции, на ум обычно приходит стандартный набор аргументов, и они действительно работают.
1. Это помогает при планировании
Пока задача выглядит как абстрактное «сделать фичу», планировать нечего. Как только появляются шаги, появляется и план.
2. Оценка по времени даётся гораздо проще
Большие задачи оценивать сложно, небольшие — гораздо проще. В итоге оценка всей работы превращается в сумму оценок отдельных шагов.
3. Руководство к действию для коллег
Небольшие задачи можно эффективно распределять между разработчиками, отслеживать прогресс и понимать, где именно что‑то пошло не так.
4. Параллельная работа в команде
Если подзадачи изолированы, их можно распределить между разработчиками и делать параллельно, не мешая друг другу и не создавая лишних конфликтов.
Как декомпозиция приводит к модулям
Помимо очевидных плюсов, у декомпозиции есть менее заметный, но очень важный эффект: она помогает выделять модули в программе.Выделение модулей — одна из самых сложных архитектурных задач. Не существует универсального рецепта, да я и не утверждаю, что решаю её полностью. Но декомпозиция даёт очень мощную отправную точку.
Лучше всего это видно на примере.
Как выглядит декомпозиция на примере фичи
Представим приложение, в котором пользователь может ввести трек‑номер заказа и посмотреть, где сейчас находится курьер.
Если подойти к задаче через декомпозицию, она будет выглядеть примерно так:
-
страница для ввода трек‑номера;
-
создание трек‑номера и присвоение его заказу;
-
поиск заказа по трек‑номеру в базе данных;
-
запись географического статуса курьера в базу данных;
-
отображение текущего положения курьера на карте.
Что меняется, если смотреть на задачу через бизнес-действия
Посмотрим на задачу не с точки зрения экранов и таблиц, а с точки зрения бизнес‑действий.Бизнес‑действие — это то, что наблюдаемо извне и имеет ценность для бизнеса. Это не «страница» и не «поле в базе», а конкретное действие системы.
Если переписать нашу задачу в этих терминах, получится такой список:
-
сгенерировать уникальный трек‑номер;
-
сохранить трек‑номер при создании заказа и вернуть его;
-
найти заказ по трек‑номеру;
-
получить текущее местоположение курьера;
-
сохранить местоположение курьера;
-
вернуть местоположение курьера по заказу.
Как из списка действий начинают проявляться модули
Следующий шаг — сгруппировать эти действия по смыслу.
Про заказ:
-
сохранить трек‑номер при создании заказа и вернуть его
Про трек‑номер:
-
сгенерировать уникальный трек‑номер;
-
найти заказ по трек‑номеру
Про геолокацию курьера:
-
получить текущее местоположение курьера;
-
сохранить местоположение курьера;
-
выдать местоположение курьера по заказу
После такой группировки модули начинают проявляться сами. Мы ещё не выбирали архитектурный стиль и не спорили про микросервисы. Мы просто разложили задачу и посмотрели, какие смыслы из неё следуют.
Чёрным цветом обозначен существующий модуль, зелёным — новые модули
-
хранить ли трек‑номер прямо в заказе или вынести трекинг в отдельную модель;
-
делать ли отдельную таблицу или даже отдельную базу данных;
-
насколько мелко дробить систему.
В стартапе с жёсткими сроками разумно сделать проще и уже потом выстроить модульную систему. В долгоживущей системе, наоборот, имеет смысл подумать о границах заранее. Но ключевая мысль в другом: декомпозиция уже дала нам материал для этих решений.
Когда же мы проявили эти модули, пришло время соединить их вместе. Для этого используем простое правило: главное приложение может использовать модули только таким образом, каким модули сами позволяют ими пользоваться — через публичный API.

API в данном случае используется в значении публичной границы, которую мы намеренно оставляем видимой для всех пользователей этого API
Если сложить всё воедино, то приложение управляет модулями, обращается к ним через публичный API и не лезет внутрь их реализации. Этот API не придуман абстрактно. Он напрямую вытекает из тех бизнес‑действий, которые мы выписали на этапе декомпозиции.
Что такое атомарный коммит
Атомарный коммит — это самостоятельный кусочек логики, который можно понять отдельно от общей логики. Один коммит — одна идея.
Почему атомарные коммиты упрощают работу с кодом и историей
Атомарные коммиты приносят очевидную пользу: легко откатывать изменения, переносить между ветками, ревьюить, находить «плохие» коммиты с помощью git bisect.
Хорошие атомарные коммиты работают как слой документации, что‑то среднее между комментариями в коде и внешней продуктовой документацией. git blame позволяет увидеть не просто строку кода, а контекст её появления: зачем она была добавлена и какие ещё изменения с ней связаны. В больших и старых кодовых базах это часто спасает часы, а иногда и дни работы.
Как атомарные коммиты тренируют навык декомпозиции
Но есть менее очевидный, но очень важный аспект: атомарные коммиты тренируют навык декомпозиции.
Чтобы написать задачу серией атомарных коммитов, разработчику приходится каждый раз отвечать на вопрос: «Что здесь является отдельным, законченным шагом?». Это и есть декомпозиция.
На практике я вижу две основные проблемы:
-
git является сложным инструментом, с которым трудно перейти «на ты»;
-
дробить большую задачу на маленькие шаги — сложная задача сама по себе.
Атомарные коммиты решают вторую проблему через регулярную практику. Повторение работает лучше любых теорий.
Как писать атомарные коммиты на практике
Всё сводится к очень простому процессу:
-
Декомпозиция. Хотя бы мысленно расписываем по шагам, как будет решаться задача.
-
Группировка кода. В один коммит попадает то, что решает одну логическую задачу и изменяется вместе. Например, тесты + реализация или отдельно модуль + отдельно его использование.
Что делать с правками и ревью
Частый страх: «Я выстрою красивую цепочку коммитов, а потом придётся всё переделывать». Если важна чистая история, используйте:-
git commit ‑fixup <my‑bad‑commit‑hash>
-
git rebase ‑interactive ‑autosquash master
Если история не критична — просто добавляйте новые коммиты. Ничего страшного.
Как понять, что коммит атомарный
Чёткого критерия нет — все зависит от контекста.
Но есть простой лайфхак: если название звучит как «X и Y», скорее всего, это два разных коммита. Например: «Создание трек‑номера и присвоение его заказу».
Лучше сделать так:
-
«Создание трек‑номера»
-
«Присвоение трек‑номера заказу»
Какие выводы можно из этого сделать
Декомпозиция важна не только для планирования и оценки задач — она помогает проектировать архитектуру и выделять модули.
Атомарные коммиты — это не просто аккуратная история в git. Это доступный способ тренировать навык декомпозиции каждый день.
Путь в тысячу ли начинается с первого шага. В разработке этот шаг часто выглядит как один маленький, осмысленный коммит.