Управление кодом в GIT

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

Видео версия заметки здесь Управление кодом в GIT - от фикса до запуска. Предыдущие заметки на эту тему:

- Удаленный GIT, слияния и конфликты проще некуда

Учимся работать с GIT проще некуда

Я видел, что TFS допускает создание отдельных веток и пару раз мы делали это, но они создавались очень долго. А когда нужно было сливать что-то, то есть делать операцию merge, то этот процесс тоже был не из самых быстрых. Наверно поэтому в TFS все коммитили прямо в основную ветку. 

При таком подходе система управления кодом превращается в мусорщик в который все кидают все, что захотят и тестирование происходит уже после того, как код попал в репозиторий. Из-за этого компания сталкивалась с серьезной проблемой – перед датой релиза нужно было обязательно протестировать то, что программисты написали за полгода. И чтобы сделать это, за полтора месяца до релиза разработка останавливалась и начинались два спринта по три недели только на тестирование и исправление багов. 

Тестируя в мастере и исправляя баги в мастере мы создаём вероятность регрессии. За полтора месяца мы должны исправить все баги и убелиться, что исправления багов не добавили регрессии, потому что тесты. . . Знаете сколько раз откладывали релиз из-за того, что тестировали в мастере? Ни разу, просто после релиза код никогда не устанавливали на сервера. Клиенты просто видели только первый сервис пак. 

Я не знаю внутренностей Майкрософт и Apple, но судя по тому, что я вижу, у них примерно то же самое. Apple объявляет новые версии своих ОС в июне на выставке для разработчиков и после этого новая разработка для данной ОС замораживается и в течении трёх месяцев идёт тестирование. 

В случае ОС это понятно, у Microsoft всегда был такой подход – выкатывать новые изменения раз в два или три года, но значительные изменения. Apple выкатывала новые версии каждый год и практически вынудила Microsoft изменить свой подход. Сейчас MS пытаются выкатывать изменения каждые полгода и отчасти поэтому изменения потеряли яркость и нет Уау, потому что количество изменений за полгода оказывается небольшим. 

Но в современном мире Web на много более эффективным является подход, когда код доставляется регулярно, можно даже каждую неделю, а некоторые отгружают его каждый день и это легко достижимое благодаря GIT. 

Наша компания перешла с TFS на GIT, но программисты продолжали мусорить в master кодом, который никто не тестировал. Единственная разница – теперь код хотя бы проходит Code Review. 

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

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

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

Итак, программист начинает работать над каким-то багом и создаёт новую ветку #1. Потом создаёт ветку номер #2 и так далее. 

У каждого тестера был собственный сервер, на котором он тестировал код. На этом сервере создавалась ветка QA от мастера и когда тестер начинал тестировать, то он сливал фиксы на свой сервер и тестировал. 

В те времена мы не делали ревью кода и если бы я сейчас вернулся в те времена, то я точно делал бы ревью именно на этапе до слияния кода в qa ветку. Его нужно делать до qa, потому что если после ревью выявит проблемы уже после тестирования, то после исправления кода придется снова проводить тестирование. 

Тестер тестирует код у себя на сервере в QA бренче и когда если все в порядке, то помечает баги как исправленные и готовые к запуску. 

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

Получив список, программист создаёт новую ветку LaunchYYMMDD или можно назвать ее Golive. Допустим, что клиент выбрал первый и последний фикс для запуска. Эти фиксы сливаются с веткой LaunchYYMMDD и на этой ветке запускаются тесты и QA вручную проверяет фиксы в этой ветке. Весь понедельник QA тестирует, чтобы во вторник отгрузить код на рабочий сервер. 

git checkout -b Launch20121129 origin/master 

Теперь сольем изменения в этот бренч. 10 лет назад, когда я начинал работать в консалтинге и отвечал за запуски кода, еще не было пул запросов и тогда ревью кода. Весь код попадал к QA без ревью и как я уже сказал, сейчас я бы делал его и до попадания кода в QA ветку. Тогда же мы делали ревью немного ручным способом. 

Допустим, что я нахожусь на ветке LaunchYYMMDD и мне нужно слить ветку fixdone/345321, то выполнялась следующая команда: 

git merge origin/fixdone/345321 --no-commit --no-ff 

Здесь мы выполняем операцию merge уже знакомым нам способом, но добавляем два новых ключа - --no-commit --no-ff. Они приводят к тому, что git не будет коммитить код после окончания слияния. Если выполнить после этого команду git status и git diff, то вы сможете увидеть все изменения. Хотя это и не было полноценным ревью кода, я все же уже в те времена просматривал то, что попадало в мою ветку Lanuch, просто лишний раз убедиться, что это именно то, что я хотел и все изменения хотя бы имеют смысл. Если я видел, что какие-то изменения не имеют смысла, то я их прерывал выполнением команды git reset и данный фикс убирался из запуска и откладывался на следующую неделю. 

Если все изменения имели смысл, то тогда я делал коммит этих изменений и переходил к следующей ветке. 

Повторяем то же самое с остальными ветками, которые нужно слить. 

git merge origin/fixdone/345322 --no-commit --no-ff 

git merge origin/fixdone/345323 --no-commit --no-ff 

Во вторник утром останавливается отгрузка кода на рабочие сервере – отключается deployment и бранч LaunchYYMMDD сливается с мастером на staging сервере и снова с использованием флагов --no-commit --no-ff . 

git merge origin/LaunchYYMMDD --no-commit --no-ff 

Я уже говорил, что сервер staging это как релиз, здесь уже клиент тестирует новый функционал, чтобы убедиться, что его точно все устраивает. Баги клиенты у нас обычно не тестировали, но иногда могли это делать. Наши QA так же тестируют на staging ещё раз и на этих серверах, но уже не половый тест, а только быстрый тест убедится, что все изменения попали в master и нет ошибок, которые могут появиться только в прдакшине. Дело в том, что стейджинг находился на серверах хостинга и тут могут вылететь такие проблемы, как закрытые порты или неверная работа в распределённом окружении. 

Когда тестируешь локально, то обычно не используешь кэш сервера или балансировщик нагрузки, а на staging сервере все это уже было. У нас проблемы редко вылетали на этом этапе, но на всякий случай все же протестировать не помешало бы. 

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

Если продакшин запуск прошел успешно, то коммитим изменения на staging сервере и этот коммит фиксирует запуск нашего кода в master. 

git commit -m 'launch yyyy mm dd'

Запуск завершен, можно отправлять изменения в репозиторий 

git push origin master

Таким образом у меня в master был только тот код, который уже запущен в продакшин. Нужно проверить, что на сервере? Я всегда знаю, что именно там, просто смотрю в мастер. Мастер всегда стабильный или по крайней мере должен быть таким. 

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

С моим подходом мы запуски могли делать в любой момент. Когда все мусорят в master, можно запустить его в любой момент? Нет! С моим подходом это очень просто, а в случае с Sony это мне приходилось делать много раз. Например, перед запуском фильма Amazing Spider Man нужно было срочно запустить новую landing page и мы легко сделали. 

Сейчас у нас все команды мусорят в мастер. Все, кроме нашей команды, потому что мы пишем код новых фишек в отдельных ветках и QA тестируют на своих компьютерах локально. Когда тест локально закончен, мы можем слить наши изменения с мастером и просто не может возникнуть ситуации, когда из-за нашей команды придётся отлаживать запуск. Так как merge в мастер происходит черёд одни Pull Request, его очень легко потом перекинуть в любой другой бренч, и легко откатить. 

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



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

Комментарии

Паника, что-то случилось!!! Ничего не найдено в комментариях. Срочно нужно что-то добавить, чтобы это место не оставалось пустым.

Добавить Комментарий

О блоге

Программист, автор нескольких книг серии глазами хакера и просто блогер. Интересуюсь безопасностью, хотя хакером себя не считаю

Обратная связь

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

Пишите мне