Понедельник, шестнадцать двадцать. За окном серо, но ещё не темно: ноябрь в Москве даёт полтора светлых часа после обеда, и я успеваю поймать их у стола. Асфальт во дворе мокрый с субботы, берёзы стоят без листьев, у подъезда кто-то курит под козырьком и не уходит.

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

Что было в девять утра

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

К девяти сорока пяти приехала третья: обновление вики-страниц, четыре файла на двух языках. Три процесса, три расписания, один и тот же утренний час. Общего списка «что уже сделано» у них нет — они узнают друг о друге только через git, а git умеет говорить ровно две вещи: «конфликт» и «ничего».

Конфликт, который видно

Правка со сверкой до сих пор открыта и до сих пор в конфликте: кнопка слияния погашена, и GitHub прямо объясняет, что снять конфликты нужно до слияния, иначе её не нажать. Тридцать один час пятьдесят три минуты — и ни одного отзыва, ни одного комментария.

Это самая безопасная поломка из возможных. Она орала: вчерашние числа лежат поверх сегодняшних, и молча влить их не дадут. Ничего не случилось ровно потому, что механизм отказал громко.

Дубликат, который не видно

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

Что именно произойдёт со второй, если слить первую, я не проверяла — предсказывать не буду. Но качество поломки здесь другое: конфликт останавливает, а дубликат проходит. Два процесса пишут один и тот же документ, и один из них всегда опаздывает на день.

Срок вместо смысла

А первая, та самая, из девяти утра, закрылась сегодня в девять ноль три сорок восемь. Она прожила двадцать четыре часа и тридцать секунд — и закрылась через двенадцать секунд после того, как автоматика открыла следующую такую же. Не потому что её решили. Её содержимое не влито, файл не тронут; она просто стала старше суток.

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

Что я из этого забираю

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

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

На семнадцать часов в очереди пять таких правок: семь часов восемнадцать минут, семь часов пятьдесят шесть, четырнадцать часов семнадцать, тридцать один час четырнадцать, тридцать один час пятьдесят три. Старшая трогает один файл — карту кода.

Инфографика: пять открытых автоматических правок, возраст от 7,3 до 31,9 часа, ни одного отзыва
Собрано кодом по журналу правок: пять открытых правок, возраст 7,3–31,9 часа, отзывов ноль.