Общая рамка у всех четырёх случаев
Разделение работы по непересекающимся зонам файлов защищает от конфликтов и потому применяется везде. Побочный эффект — граница зоны становится границей внимания: всё, что происходит за ней, не входит ни в чьё определение готовности. Отчёт каждого честен, сумма отчётов неверна.
- Где я стою. Общий каталог, чужая ветка, чужая копия — точка приложения команды может не совпадать с намерением.
- От чего я меряю. Разница с основной веткой и разница с базой своей ветки — два разных числа, и путать их дорого.
- Что живёт поперёк зон. Навигация, футер, единая кнопка действия — у них зона по определению общая.
- Чем я плачу за соседа. Память, процессы, вкладки — ресурс общий, а падает тот, кто в этот момент работает.
Коммит уходит в ту ветку, на которой стоит каталог
Работа шла в изолированной копии, а инструменты и выкладка запускались из общего каталога. Коммит ушёл туда — то есть в чужую ветку, отставшую на 1047 коммитов. Формально всё хорошо: файлы под контролем версий, коммит есть, история пишется.
Две беды сразу. Такая ветка не вливается целиком — отправкой откатит чужую работу. И в свой коммит легко утащить чужие незакоммиченные правки, лежащие в общем каталоге рядом.
Дисциплина простая и вся на предварительных вопросах: перед любым коммитом в общем каталоге — показать текущую ветку; добавлять только перечисленные пути, не всё разом; прочитать глазами список того, что попало в индекс. Если коммит уже ушёл не туда, снимается мягким сбросом на один шаг назад — рабочее дерево при этом не трогается, файлы живы на диске и переносятся в свою копию. Жёсткий сброс здесь снёс бы чужие правки.
Приёмка переноса — не «ветка запушена», а два факта: коммит содержится в основной ветке, и каждый файл в ней существует поимённо.
Спасая чужое, меряй от базы ветки
За один день умерли два чата, оставив незакоммиченные правки в своих копиях, — и чистка копий в этот момент уже шла, каталоги подлежали удалению. Первый замер сделали привычным способом, разницей с основной веткой: 19 добавлений и 13 удалений в файле реестра ошибок.
Замер против базы самой ветки дал 7 добавлений и 0 удалений. Тринадцать «удалений» были не работой чата, а отставанием его копии: ветку создали от коммита, где этих строк ещё не существовало. Вливание по первому замеру откатило бы тринадцать строк чужой работы, уже лежащей в основной ветке.
| Вопрос | Замер | Для чего годится |
|---|---|---|
| Что наработал чат | Разница с базой своей ветки | Спасение — только это |
| Чем ветка отличается от основной | Разница веток от точки расхождения | Приёмка, не спасение |
Коммит спасённого идёт только в родную ветку копии и только перечисленными путями, с предварительной проверкой текущей ветки. Временные файлы не спасаются. Спасение не закончено, пока ветка не уехала на хостинг. Итог того дня: 958 строк двух чатов, из них экран проверки рейсов на 394 строки.
Сквозной элемент устаревает в момент сдачи
Пакет сводил три страницы одного направления в связный сайт: общая навигация и единая кнопка действия. Пока он шёл, соседние пакеты выкатили в прод четвёртый раздел и каталог кейсов. Оба появились после того, как состав навигации был зафиксирован, и ни один в неё не попал: новый раздел ни на кого не ссылается, и на него не ссылается никто — ровно та болезнь размытой точки входа, ради которой пакет и затевался.
Виноватых нет: у первого пакета в рамках были только три страницы, у соседнего — только его каталог. Каждый отработал по своему заданию и в свои файлы. Системная часть в том, что у сквозного элемента зона по определению — все страницы направления, а вводящий его пакет всегда сдаётся раньше, чем появится последний раздел.
Проверка перед закрытием: перечислить каталоги направления и посчитать маркер навигации в каждом из основной ветки. Ноль хотя бы у одного — навигация неполная, и нужна карточка с рецептом, а не строка в отчёте.
Общая память: платит не тот, кто насорил
За сутки два чата умерли, не сдав работу, а приложение пришлось переустанавливать. На замере среды оставалось свободно 3 ГБ из 16. Один чат с одной открытой проверкой безобиден; зон несколько, у каждой по нескольку исполнителей, а тяжёлые процессы переживают сами сессии — деградация копится незаметно, и падает тот, кто в этот момент работает.
Честная оговорка. Часть счётчика браузерных процессов позже объяснилась личным браузером человека, и та атрибуция снята — разбор наследованных фактов у нас отдельный. Практический вывод держится на другом, неоспоренном факте: два чата умерли на середине, и работа в них была незакоммиченной.
- Запрос из командной строки вместо браузера по умолчанию. Код ответа, заголовки, наличие блока на странице — всё это одна строка без единого тяжёлого процесса. Браузер нужен там, где без него нельзя: консоль, сетевой лог, живой клик, вёрстка глазами.
- Гасить превью сразу после проверки и не копить вкладки: список своих превью перед продолжением работы должен быть пуст.
- Коммитить промежуточное. Пакет из пяти страниц — пять коммитов, а не один в конце. Умерший чат с промежуточными коммитами оставляет хвост, который подхватят; умерший с накопленным — потерю.
Приёмка после того инцидента показала 0 незалитых коммитов и 0 изменённых файлов в каждой копии: три исполнителя успели сдать до падения. Данные уцелели — но только потому, что повезло со временем.
Что делать у себя
- Перед коммитом в общем каталоге — показать ветку. Одна команда закрывает самый дорогой из тихих провалов.
- Спасая чужое, мерить от базы его ветки. Разница с основной веткой в этой задаче отвечает не на тот вопрос и подмешивает чужую работу в откат.
- Сквозной элемент — последним или с рецептом. Иначе результат устаревает без единой ошибки исполнителя.
- Ресурс, переживающий сессию, гасить за собой. Правило «закрывать превью» перестаёт быть гигиеной в тот момент, когда чаты начинают умирать «без причины».
- Ставить промежуточные коммиты обязательным пунктом задания. Не пожелание в конце, а строка в постановке.
Во всех четырёх случаях внутри своей рамки отработали правильно. Ошибка целиком жила на стыках — там, где ни у кого нет определения готовности.