В ночь с пятницы на воскресенье, или Затертые изменения
[Об авторе: Владимир Железняк — 17 лет в отрасли, много всякого повидал, был многократно уволен, взлетал и падал.]
Тема вызвала большое бурление в фейсбуке, так что считаю нужным разобрать более детально. У этой истории есть важное свойство — каждый моментально формирует свой единственно-правильный ответ. Плохо, что эти ответы не совпадают :) :
Один синьор любил работать в тишине и часто задерживался на работе. Как-то в пятницу вечером он глубоко погрузился в код, разогнался и, абсолютно незаметно для себя, отрефакторил полпроекта. Покрыл тестами, закоммитился, запушился и ушел домой спать. Я вообще не знаю, выходил ли он из офиса в ночь с пт на вс.
Второй синьор пришел в понедельник с утра пораньше и обнаружил, что мердж его почти готовой и долгожданной фичи теперь из-за рефакторинга из банальной задачи превратился в огромного монстра. Ситуацию усугубило очередное письмо «сколько можно ждать! давай немедленно!» от заказчика. Второй взял и, никого не дожидаясь, решил проблему — откатил коммиты Первого и влил свои.
В середине дня на работу пришел Первый. Увидел. Осознал. Пришел в ярость. Пошел бить морду.
История
Ниже будут комменты читателей, и здесь однозначно виноват:
Менеджер:
- Не прав менеджер в данной ситуации. Это фейл исключительно менеджера.
- На 90% проблема менеджера.
- Факт, что пипл от скуки начинает рефакторить в пятницу вечером, говорит о плохом манажэменте.
- Виноват начальник.
- Всю вину несет начальник.
- ПМ-у двойка.
Первый:
- Синьор-помидор сделал инициативу, никого не предупредив, не получив разрешения, вышел за рамки своих заданий и начал рефакторинг области пересечения, то он на 100% виноват. Тут даже не о чём говорить.
- Тот, кто перелопатил, сделал это через зад.
- Первый террорист какой-то. Такие вещи планируют за полгода вперед, несколько раз отодвигая от послерелиза до послерелиза.
- Виноват первый синьор.
- Че первый синьор без ревью рефакторинг пушил?
- Первый программист — не командный игрок.
Второй:
- Второму гит сказал — мердж затрёт чьи-то изменения — и он сознательно сказал ок — затирай, лишь бы свою фичу выставить, и никто бы недо...вал.
- Второй явно уже тайно думал, что первый мудак раз вместо бранча свой маневр с откатом запушил в основную ветку и никому ничего не сказал.
- Хто перший закомітався, того і тапки. Другий мав замерждитись.
- Если так уже случилось, и второй сеньор получил лично такое письмо, то логичнее было бы подождать менеджера и спокойно обсудить ситуацию.
Неправильный процесс:
- И все бы было хорошо, если бы они знали git не на уровне push/pull.
- В компании должен быть налажен процесс рефакторинга. Если кто-то хочет сделать рефакторинг, то он за N дней уведомляет сотрудников таких-то ролей, получает от такой-то роли подтверждение и потом делает.
- Проблема не в людях, а в структуре. И я бы со структурой разбирался.
- Нефиг в психологию лезть, с процессами разбирайтесь.
- Процесс херовый.
- Над этими двумя должен быть один старший программист, который дает ответ, что делать в таких ситуациях.
- На Западе корпорации имеют четкую полувоенную структуру со всеми вьітекающими.
- Купить первому девелоперу хорошие изолирующие наушники, чтобы он работал в одно время с остальной командой, а не партизанил ночью.
Все вместе:
- Все трое отличились.
- Тут много прекрасного: и залитый в основной бранч «ре-фак-торинг» (третий слог должен быть английскими буквами), и подход «выкатим фичу, потому что заказчик просит», и еще пара вещей по мелочи.
- Все трое живут в вьідуманном маня-мирке.
- Виноваты первый программист и менеджер в пропорции 60 на 40.
- Усіх розстріляти :).
- Со стороны «первого синьора» это была демонстрация тотального неуважения к своим коллегам, независимо от того, какой объём работы он там покрыл. С другой стороны, «второй синьор» тоже включил д’Артаньяна и без попыток связаться с коллегой, под звук сливного бачка, спустил его наработки в сточную канаву. Вообще, если такая ситуация произошла, то имеет место элементарное неуважение в коллективе, значит виноват менеджер.
Нужно больше контекста и вообще:
- Не надо забывать, что мы видим ситуацию со стороны одного из участников (у двух других будут свои истории и своя правда).
- Ситуация выдуманная.
- Ситуация вполне реальная и знакомая.
- Это просто какая-то феерия глупости.
- Во-первых, почему рефакторинг пушится в основную ветвь? Во-вторых, почему отрефакторенный код не прошел ревью?
Что меня удивило
- Умение быстро находить виновного. Только несколько человек задали вопросы, ведущие к уточнению ситуации «а на какой стадии проект-то?», «какие практики были оговорены?», «кто вообще за что отвечает?».
- Большинство сфокусировалось на поиске виноватого, и только несколько человек, включая Ignat Alexeyenko, Dmitriy Rossokhovatskiy, Dmytro Lepeshkov, Artem Serdyuk, больше говорили о решении. Т.е. был фокус на «кто виноват», а не на «как предотвратить в будущем».
Что можно было сделать?
Разбирать будем по таймлайну, в том порядке, в котором события происходили. Дальше текст будет очень похож на программу. Или на скрипт для автоматизированного тестирования.
0. Построить процесс так, чтобы ситуация была вообще невозможна
Это соответствует здравому смыслу. Но не во всем он есть, и не везде он нужен.
Хорошая идея, и давайте вернемся к ней позже. В конце концов, не во всех фирмах процесс зафиксирован. А иногда люди делают что-то, еще не предусмотренное процессом. А иногда процесс предусматривает всё, только он становится настолько большим и неповоротливым, что его знает только автор. Баланс между полной анархией и полной бюрократией очень сложно найти — всегда найдутся недовольные.
1. Пятница вечер, все ещё на работе. Первый еще не разогнался
Первый
Что может сделать Первый? Если он планирует что-то мощно рефакторить, то хорошо бы об этом сказать. Сказать-то хорошо бы было, но:
- Первый может вообще не планировал рефакторить, тем более мощно. Он просто писал код для своей фичи. Если кто-то всегда наперед знает, к чему приведет написание его кода — то это новое слово в оценке сроков.
- Первый чувствует себя самым крутым на проекте. Это может быть более оправдано в ситуации «я на проекте уже год, и я сеньор, а второй — миддл и всего пару недель тут, а менеджер — вообще без технического опыта». Оправдание слабое, и часто является обратной стороной от «я знаю здесь всё, я отвечаю за этот проект, и мне лучше писать код, а не тратить время на говорильню».
Первый мог вынести свою фичу в отдельную ветку с самого начала. Давайте посмотрим, в каких случаях это сомнительно. Именно сомнительно, но занятый кодом человек может не подумать в эту сторону:
- самое-самое начало проекта;
- когда изменения планировались небольшими, да и «вот закончу с кодом, займусь оформлением перед коммитом»;
- на многих проектах в рабочую ветку можно кидать фиксы с пост-ревью — главное, чтобы в продакшен не ушло без проверки. Да, это холиварное место, а частота и серьезность деплоев сильно зависят от команды, проекта, заказчика.
Примечание: очень хочется сказать, что накосячил именно Первый и именно тут. Все могут ошибаться, главное — что произойдет дальше.
Второй
Второй мог сказать «я тут заканчиваю фичу, планирую в пн отдать». Может, даже сказал, но это не помогло:
- например, Второй мог сказать это только Менеджеру, а Первый не слышал;
- Второй мог сказать это Первому между делом, например, на стендапе, а Первый мог пропустить мимо ушей. Тем более, что на этом этапе никто из них не ожидал конфликта кода;
- Первый мог придерживаться принципа «кто первый встал — того и тапки. Я изменения внес, тесты прошли — дальше не моя проблема». Сомнительный принцип, но я такое видел от мегаэкспертов. У людей, которые на голову превосходят окружающих в технической квалификации, такое бывает.
PM
PM может спросить у засидевшегося Первого перед уходом «а что ты сейчас делаешь и какие планы?»
- если Первый уже понимает, к чему дело идет, то он может сказать «я собираюсь мощно отрефакторить». Ситуация завершается банальным «ну ок, только в главную ветку не вмердживай — у нас там выкатка важной фичи в пн. Как будем мерджить — в пн и обсудим»;
- если Первый еще не понимает, во что это выльется — то вопрос ничего не меняет.
Вообще, довольно необычный вопрос для пятницы вечера. Наверное, встречается в реальной жизни у нас не чаще, чем принцип «менеджер уходит с работы последним и приходит первым».
2. Пятница вечер, все ещё на работе. Первый уже погрузился в код
Этого пункта могло и вообще не быть. По моему опыту, любители посидеть допоздна разгоняются только тогда, когда никого не остается в радиусе пяти метров. Оно понятно, меньше шансов, что прервут.
Первый
Мог оторваться от кода и сказать «я тут всё мощно переделываю» и обсудить «зачем? что именно? когда будет готово? учел ли ты вот это и вон то?». Обсуждение, может и полезное, только код после этого уже написан будет не раньше понедельника. И вообще, что это за программист, который в пт вечером предпочтет совещание вместо кодинга?
Второй / PM
Мог заметить, что Первый что-то быстро пишет, и спросить «а что это ты тут делаешь?»
Никто не любит, когда его отвлекают, а некоторые даже работают по вечерам именно ради уменьшения количества прерываний. Так что если задать вопрос раньше, чем человек войдет в состояние потока — то ему пока не понятно, чем он будет заниматься. А если позже — так он запросто решит, что из-за дурацкого вопроса, которому место на синкапе, ему теперь заново разгоняться... проще пойти домой. Что тоже является решением.
Мне кажется, что вопрос «а что это ты делаешь?» в состоянии потока могут простить либо большому начальнику, либо большому авторитету. Все остальные — просто получат по ушам.
Кроме того, если не было предварительной договоренности, то на выходных обычно ничего не происходит, так что вопрос звучит глупо.
3. Ночь с пятницы на воскресенье, на работе только Первый
Вот так сядешь попрограммировать на 15 минут в 10 вечера, а потом обнаруживаешь себя в час ночи, чинящим ошибки на продакшене... © Yuriy Silvestrov
Первый
Сфокусирован на работе, видит только код, потрясающая эффективность, когда чувствуешь сверхсилу и за день делаешь двухнедельную работу. Весь мир исчез, туннельное зрение, редкие прерывания на «залить свежий кофе сверху, вылить переработанный кофе снизу».
В таком состоянии от человека нельзя ожидать каких-либо осознанных действий за пределами узкой задачи. Высокая концентрация внимания на одной задаче не оставляет внимания для чего-либо еще.
Второй / PM
Можно опять-таки позвонить Первому или хотя бы проверить логи сервера. Глупо звучит, правда?
4. Воскресенье, Первый уползает с работы
Полностью выложился, проделал огромную работу, последними усилиями причесал код и залил на сервер. Что еще мог сделать:
- написать в общий чат «я всё переделал и пошел спать». Я думаю, что на эмоции и действия Второго это никак не повлияет;
- таки выпилить изменения в отдельную ветку. Несколько команд гита — и всё работает. Да, это правильное решение, кроме:
- может тупо не быть сил или времени. Кто всегда все дела доводит до конца — отпишитесь в комментах; :)
- человек искренне считает, что его изменения однозначно полезны, и пусть ими все начнут пользоваться как можно раньше. Тем более, что в понедельник с утра он будет на работе и всем всё расскажет.
5. Понедельник, на работу приходит Второй
Первый спит, PM еще не пришел, Второй видит большие изменения, которые нафиг порушили его работу. Ну и письмо от заказчика «срочно нужно» тоже видит. Можно предположить, какой вихрь мыслей пролетает у него в голове: «тут теперь дофига работы», «мог бы и сказать», «что я теперь делать буду», «вот козёл», «я же обещал заказчику!», «понедельник — день тяжелый». И всё завершается мыслью «я должен зарелизиться сейчас! Эмоции и разборки — потом».
Как зарелизиться побыстрее? Выкатить чужие непроверенные изменения на прод под свою ответственность? Нет! Нужно вернуть в состояние «как было».
Что мог сделать Второй именно на этом этапе:
- Зарелизиться. В конце концов, в git бэкап есть и откатить не сложно. Говорят, где-то в заповедниках еще встречаются команды без version control, но даже они имеют практики архивации кода на грампластинки.
- Подождать прихода менеджера. В конце концов, сроки больше в его зоне ответственности, он определяет приоритеты — пусть он и разбирается. Это вполне нормальное решение в командах с жесткой иерархией и совершенно дикое для команд, где есть инициатива. И если это ожидание привело бы к срыву деплоя — прилетело бы всем. Просить о повышении зарплаты и об отпуске в обозримом будущем станет куда сложнее.
- Позвонить менеджеру и переложить решение на него. Менеджер оказывается в ситуации Первого, только он еще и не может заочно оценить масштаб переписанного. Что может сделать Менеджер:
- сказать «откатывай и релизься». Это выведет Второго из последующего конфликта и упростит дальнейшие разборки;
- сказать «подожди меня и Первого». Это приводит к конфликту с Заказчиком, что тоже может быть вполне ок — от ситуации зависит.
6. Понедельник, на работу приходит ПМ
Второй
- можно сказать Менеджеру;
- можно не сказать и продолжить кодить, ибо некогда языком молоть, релиз важнее. Спорно, конечно.
PM
Уже рассмотрели в предыдущем разделе, только разбираться в масштабе разрушений проще. Конечно, если PM технически грамотный и хорошо понимает написанное.
7. Понедельник, на работу приходит Первый
Первый
Прежде чем перейти к возможным действиям, давайте посмотрим на состояние Первого:
- отдохнул ли он на выходных? Нет, он выложился по полной. Усталый человек действует на автопилоте и более нервно, чем обычно;
- он может чувствовать гордость за «я без просьбы менеджера овертаймил» и за «я классно переписал застарелый говнокод». За это обычно хвалят;
- он может чувствовать страх — ведь изменения не были согласованы, это нарушение дисциплины и командной работы. Да и если он видит хоть какие-то недостатки в написанном коде, то и другие тоже могут увидеть. А профессионал очень редко скажет на свой код, что он идеален — всегда видно, как сделать лучше;
- он может тревожиться — ведь меня будут оценивать, а после этого либо похвалят, либо обругают. Люди часто боятся внешней оценки, это нормально для нас;
- он может чувствовать вину — ведь на работу пришел позже обычного. Конечно, планировал прийти пораньше или хотя бы со всеми, но... После таких выходных на работу вовремя обычно не приходят, хотя и стараются;
- он может чувствовать отвращение — ведь после очень напряженных выходных впрягаться в понедельник с утра ой как не хочется. Это организм намекает, что либо отдых сейчас, либо хроническая болячка годам к
35-40; - если есть хоть чуть-чуть страха, вины и тревоги, то обязаны включиться механизмы самозащиты, и в голове будут крутиться фразы «я молодец, я это таки сделал», «я всё сделал правильно», «да кто они такие, чтобы меня оценивать», «сейчас я им всё объясню», «если они не оценят моих достижений — свалю нафиг, давно пора». Если самоуспокоения не хватило — то включится гнев.
Итак, Первый пришел на работу и видит, что в главной ветке его изменения откатили. Что он может сделать:
- воспринять это спокойно. Ага, его кто-то оценил и оценил плохо. И это новость для уже накрученного человека. Мало кто способен в такой ситуации воспринять это спокойно;
- Важное примечание: негативно оценили здесь не Первого, и не его навыки, а его действия. Но воспринимается это именно как атака на личность. Накрученному человеку сложно различить «ты плохой», «ты плохой специалист» и «ты плохо поступил в этот раз». Эти три совершенно разные ситуации обычно сливаются в самое жесткое «ты плохой».
- Есть методики быстрого самоуспокоения, но ими сложно начать пользоваться. Повторять «я спокоен» помогает отнюдь не всем. Мультик в тему.
- молча обидеться и вместо работы полезть по развлекательным и работодательным сайтам. Это нормальная человеческая реакция, если обидчик воспринимается сильнее;
- пойти чинить разборки. Обычно люди так поступают, если обидчик выглядит сравнимым по силе. Не физической, конечно.
Второй
В каком эмоциональном состоянии Второй?
- он может быть глубоко сконцентрирован на деплое. Состояние потока, обработка окружающего мира идет с низким приоритетом;
- он может гордиться — он принял решение и таки успеет сделать деплой;
- он может злорадствовать — это если Первый ему чем-то насолил раньше, а теперь подвернулась возможность восстановить справедливость;
- Злорадство — положительная эмоция, пусть и социально-неодобряемая. Т.е. ты радуешься и чувствуешь свою вину за это. Если есть вина — то идет и самооправдание.
- Понятая по-разному справедливость, месть, злорадство — в жизни айтишников таки встречаются. Такие случаи как бомжи — о них не принято помнить и о них не принято говорить, а они есть.
- он может переживать — насколько правильным было его решение;
- он может нервничать — проактивность очень любят в переводных статьях, а со школы вбивают «я начальник — ты дурак»;
- он может чувствовать вину — если релиз в понедельник, и релиз срывается, то на «всё ли я сделал для релиза?» ответ «нет, можно было на выходных выйти»;
- если есть хоть чуть-чуть страха, вины и тревоги, то включаться механизмы самозащиты «я всё сделал правильно», «они уроды», «уволюсь», «пусть только попробуют мне что-то предъявить», «плохой заказчик, дурной проект, идиот менеджер, самоубийца-коллега».
Что Второй может сделать?
- Если уже спешить для деплоя не надо — можно поднять тему самому. При правильных словах конфликт бы решился за пять минут. Сравните две фразы, по сути — одно и то же сказано, а восприятие меняется.
- «ты перехреначил проект, из-за твоих шаловливых ручек мы не могли зарелизиться. Я откатил все кривые правки, сегодня после обеда расскажешь, что ты хотел сделать — может, таки и пустим в общую ветку»;
- «сегодня я начал мерджить правки для релиза и это оказалось сложно из-за изменений в основной ветке. По требованию заказчика, сегодня фича должна выйти на сервер, так что временно я откатил эти изменения. Ближе к вечеру давай обсудим, ок?»
- «ты перехреначил проект, из-за твоих шаловливых ручек мы не могли зарелизиться. Я откатил все кривые правки, сегодня после обеда расскажешь, что ты хотел сделать — может, таки и пустим в общую ветку»;
- Если спешить еще нужно — то действия остаются прежними: писать код, и пофиг на эмоции Первого.
PM
В каком состоянии менеджер? А мы не знаем. Может, он на выходных встретил девушку своей мечты и прообщался с ней полдня. А может, тёща помыла новый MacBook Pro c Доместосом, а потом объяснила, что за своими вещами нужно уметь следить самому. А может, у него произошли оба этих события одно за другим, и в голове у него некоторая каша.
Что может сделать менеджер?
- самоустраниться «вы взрослые люди, разберитесь сами» или «обсудим на ретро». Если это рациональная оценка, что эти двое справятся сами к выгоде проекта, тогда ок. Если они не справятся — запросто уволятся оба;
- сказать «успокойся». Обычно это самый простой способ сорвать чужую крышу. А если сказать «успокойся, ты не прав, сейчас я тебе поясню, как правильно» — то можно даже в челюстно-лицевом отделении побывать;
- заняться вопросом именно кода;
- с технической стороны здесь нечего обсуждать. git рулит;
- с организационной — и Первый и Второй заняты самонакручиванием. Даже если они не уволятся сейчас, они сделают большой шаг к увольнению — это будет ниже КПД и на них меньше можно будет положиться.
- фасилитировать разговор и помочь коллегам научиться самостоятельно такое разруливать. Наверное, идеальное решение, если есть время, авторитет и нужные навыки;
- что таки нужно сделать:
- вслух подчеркнуть заслуги: Первый работал на выходных и сделал нужное дело. Второй — таки запустил релиз;
- признать их право на эмоции. Тут очень много чего есть сказать, только много букв будет;
- концентрироваться не на поиске «кто виноват», а на «что делать прямо сейчас?»
Процесс
Я понял, нужно просто запретить людям делать ошибки. Тогда сразу программисты классный код писать будут, причём быстро.
Не понимаю, почему такое очевидное решение еще не реализовано законодательно. ©
Никакие две поломки не должны вести к срыву миссии. Никакие три поломки не должны вести к гибели экипажа. © из космонавтики
А вот тут уже задача менеджера. Что можно сделать:
- запретить работать на выходных. Это сделает мотивацию предсказуемой. Ужасно предсказуемой;
- ввести жесткую систему отчетности с автоматическим отслеживанием возможных конфликтов. Пусть сдохнут от бюрократии;
- таки использовать GitFlow с самого начала. В отличие от предыдущих двух идей — эта стоящая. Впрочем, у этих же людей мог возникнуть конфликт, например, про «у меня мышка на выходных сломалась, я взял твою», «я взял твой монитор», «нам на проекте давно было пора ввести единый стандарт кода, поэтому я везде заменил пробелы на табы и выровнял switch»;
- уметь работать с чужими эмоциями.
Мысли вместо вывода
- Искать виноватого проще, чем предотвращать ситуацию в будущем.
- Несколько мелких ошибок легко суммируются до серьезного конфликта. Ну действительно, можно ли всерьез обвинять человека, который решил сам добровольно поовертаймить? А человека, который решил выполнить обещанный деплой? А менеджера, который на выходных не долбал сотрудников вопросами?
- Мог ли каждый из участников вытянуть ситуацию? Мог. Более того, каждый день вытягивают. Только когда вытянули — это не заметно, а когда все провалили — вот тут уже ой.
- Получился длинный разбор короткой истории. Можно и еще длиннее сделать. А можно взять вот эту выжимку — там из каждого абзаца можно такую статью написать :)
PS: Планирую статью по сложным ситуациям в жизни айтишника.