software-development
February 8, 2023

Как пасти (с)котов. Часть 2: Git

Продолжаю изливать потоки знаний о разработке. Теперь про репозитории и релизы.

Разработка ПО глазами интернет-обывателей.

Первая часть тут. Продолжение тут. Как нанимать тут.

Git

Для начала расскажу почему именно Git.

Дело в том что Линус Торвальдс совершил не одну единственную революцию в своей карьере. Про создание Линукса в курсе все айтиштики, но была еще одна, куда менее заметная — он создал Git.

И на сегодняшний день git победил всех своих конкурентов. Раньше были всякие cvs, svn, mercurial, bazaar — все они по большому счету отошли в прошлое, уступив место git.

CVS и Subversion (SVN) я последний раз использовал в 2007м, Mercurial — в 2012м.

Вообщем, шансы на то что вы будете иметь дело с чем-то отличающимся от Git в 2023м году — в районе нуля.

Едем дальше.

Падите ниц, смертные!

Его величество «репозиторий»

Если в кратце — это такое хранилище исходного кода, туда все ваши разработчики заливают изменения, доработки и правки:

git push

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

Но тут у нас все же про разработку.

Из репозитория же эти изменения забираются и сопоставляются с локальной копией:

git pull

Из репозитория код выгружается в CI-систему, для автоматической сборки и развертывания на стендах.

Если совсем по-хорошему:

в CI системе также формируется релизная сборка.

Проще говоря локально ручками никто готовый проект не собирает. Если вы конечно не е#нутые и не работаете в одиночку.

Думаю из описанного становится очевидно что репозиторий это и точка отказа и первая цель для взлома и утечек — вообщем наверное самое важное звено при совместной разработке.

Поэтому его надо защищать и внимательно настраивать доступ и права. И конечно не забывать про бекапы. Никогда не забывать про бекапы.

Ветки, ветки everywhere!

Ветки и релизы

Первое с чем вы столкнетесь при создании репозитория это ветки (branches). Общий смысл ветки — создать сквозной срез всего репозитория.

Коммиты (изменения) добавляются последовательно в конкретную ветку с названием.

Так и формируется версия:

набор исходного кода в определенном именованном срезе репозитория.

Существует много разных схем ведения веток и создания релизов, с разной степенью применимости. Ниже я расскажу про свою, которую применяю в своих проектах по заказной разработке много лет.

Отдельно про Git Flow

Все случаи применения этой модели для командной разработки, что я видел заканчивались очень большим п#здецом проблемами:

  • сильное разъежание версий между продуктовой сборкой и текущей;
  • проблемы со сведением изменений, частая утеря правок;
  • куча «мертвого груза» в репозитории: персональных или feature-веток, которые были брошены.

Почему так происходит?

В основном из-за отсутствия самоконтроля, git flow — в первую очередь для умных, затем для стабильных: когда есть более-менее стабильная кодовая база и нет кранчей и гонок за релизом.

Поэтому в реалиях стартапа или заказной разработки — «git flow» очень быстро станет проблемой:

Не будете же вы в самом деле проводить ревью каждого коммита через pull-request -> accept -> merge ?

Это имеет смысл когда вы уже давно сделали продукт, он стабилен и продается. А теперь вся ваша работа это делать мелкие правки и лежать на пляже стричь купоны.

Моя схема

Я делаю четкую и однозначную разбивку на текущую версию, которая находится в разработке и завершенные релизные версии:

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

Текущая разработка происходит в ветке develop, релизные же ветки именуются по дате релиза: release_02.10.22

Релизная ветка создается из «замороженного» develop в день завершения спринта и подтверждения от тестировщиков что все работает.

Красивая модельная схема с релизными версиями и ветками фич.

Посмотрите на схему выше — красивая?

Они все красивые, пока на картинке.

В реальности чтобы вести номерные версии нужен changelog (список изменений) — это такой отдельный документ со списком изменений в каждой версии. Выглядит примерно вот так.

Без ченжлога, понять отличия между версиями — проблематично, специально вести ченжлог в реалиях стартапа или заказной разработки — затратно.

Даже с использованием п#здюлей мотивации и автоматических средств.

Второй важный момент это метки сборки:

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

Чтобы затем показать пользователю что-то такое:

Исторический снимок: релиз Windows 3.1

Конечно в 1991м году все было сильно проще, но номер сборки был уже тогда (см. последние три цифры в номере версии).

Возвращаемся к нашим мирским проблемам:

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

Вот тут и приходят на помощь даты в названии релизного бранча:

release_02.07.2012

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

Потому что создание релизной ветки из develop и релизная сборка происходят обычно в один день.

Соответственно у вас всегда будет возможность найти концы — исходники той версии что работает в продакшне.

To be continued..

В следующей части расскажу про тестирование и качество ПО. Думаю у многих случится разрыв жоп устоявшихся взглядов на этот непростой процесс.

Продолжение следует, не переключайте канал.