Случай, на котором это стало видно
Работа шла над разделом методики, который как раз описывает правило «мерь на свежей базе». Копия была создана от актуального состояния основной ветки. Через двадцать минут работы основная ветка ушла вперёд — и приехавший туда коммит назывался буквально: исправление ложного срабатывания на плитках-ссылках, 242 находки.
Что было бы без сверки. Замер прогнался бы на исходной базе, выдал 242 ложные находки и не сообщил бы об этом ничем: числа заполнены, разделы на месте, отчёт читается нормально. Ошибку такого рода не видно изнутри результата — её видно только из сравнения с состоянием, которое ты не проверял.
Правило, которое этот раздел описывал, сломалось на самом документе, который его писал, за двадцать минут. Мы оставили этот случай в методике как основной пример — он честнее любой формулировки.
Чистый статус ≠ свежая копия
Привычка смотреть на статус репозитория и делать вывод «всё в порядке» — самая дорогая из безобидных. Статус отвечает на вопрос «есть ли у меня несохранённые изменения», а не на вопрос «совпадает ли мой код с актуальным».
| Что случилось | Числа | Чем обернулось |
|---|---|---|
| Общее дерево отстало от актуальной ветки | 1541 коммит, статус чист | копия инструмента в дереве старше и не содержит починок: локальный прогон взял бы не тот код, и «проверка» относилась бы к другому файлу |
| Белый список цен читался из отставшего дерева | отставание 1537 коммитов | после починки список вырос 45 → 54: девять позиций «отсутствовали», хотя существовали |
| Красный тест денежной логики | дерево отстаёт на 1550 коммитов; файл на диске 704 091 байт против 1 481 520 в актуальной ветке | в чистой копии от актуального состояния — 299 из 299 зелёных. Красный тест оказался артефактом устаревшей ветки, а не дефектом |
Третья строка — самая показательная. Красный тест выглядит как находка: вот же, поймали. Потратить на него день и обнаружить, что чинить нечего, дороже, чем одна команда сверки в начале.
Второй слой: два правильных правила, которые исключают друг друга
Дальше мы наткнулись на конфликт, который стоит знать всем, кто разводит параллельные сессии по изолированным копиям.
- Правило «работай в изолированной копии» защищает от того, чтобы параллельные сессии затирали друг друга. Правильное правило.
- Правило «пользуйся накопленным слоем знаний» экономит время: сессия не начинает с нуля. Тоже правильное.
- Вместе они не работают. Замер: сессия в изолированной копии не получает накопленный слой вообще — 0 из 634 файлов, потому что хранилище привязано к пути. Обход подтвердил: из 493 каталогов проектов слой есть у восьми, и ни одного изолированного среди них.
Мелочь, которая стоит отдельного абзаца: имена каталогов
Хранилище накопленного слоя адресуется преобразованным именем каталога. Каталог с именем не из латиницы превращается в строку из одних дефисов — то есть любые два таких каталога одинаковой длины делят одно хранилище. Подтверждено реальным случаем в нашем хранилище.
Проверяется это кем угодно за минуту: заведите два каталога с не-латинскими именами одинаковой длины и посмотрите, куда лягут их данные. Мы приводим случай без путей и имён посторонних проектов — механика от этого не меняется.
Что мы из этого сделали
- Сверка свежести — первый шаг, а не пункт чек-листа в конце. До вывода «дефект» или «регрессия» проверяется, что дерево соответствует актуальному состоянию.
- Вывод «сломано» требует проверки в чистой копии. Красный результат в старом дереве не считается находкой, пока не воспроизведён на свежем.
- Отставание измеряется числом, а не ощущением. «Вроде недавно тянул» — не ответ: 1541 коммит тоже накопился «недавно».