1. Крок 1. Переносимо роботу в гілку
Льоха пішов, Олега тут нема. Сейф зібрано — Тьома проходить це сам, від початку до кінця, на тій правці reward-flow, яку хотів внести зранку. Насамперед треба винести роботу з-під main. Тьома повертається до Сашка, але на мить спотикається: як ту гілку правильно назвати?
— Сашку, я хочу окрему гілку під правку. Назвати як — є різниця?
— Для git різниці немає, — відповідає Сашко рівно. — Але по-людськи імʼя має показувати, що це за робота. fix-reward зрозуміліше, ніж test123 — за тиждень сам пригадаєш. Створювати?
— Створюй, fix-reward. І працюй тільки в ній, main не чіпай.
● git checkout -b fix-reward
Перемкнено на нову гілку 'fix-reward'
— Готово, я в fix-reward, — доповідає Сашко. — main не чіпаю.
Тьома перевіряє: так, він у гілці, main недоторканний. Між робочим процесом і експериментом тепер є чітка межа. І він ловить себе на тому, що вперше спокійно пускає Сашка до коду.
— Ну давай, — каже він майже весело. — Ламай, пробуй. Нафігачиш — відкотюсь, і край.
2. Крок 2. Правка і диф із зайвим
За старою звичкою Тьома ставить задачу коротко, не вдаючись у подробиці:
— Сашку, там із винагородою щось не те капає. Розберися з нарахуванням, ну і взагалі глянь, щоб усе було красиво.
— Уточню, — тут же озивається Сашко. — «Нарахування» — це reward-flow. А «щоб усе було красиво» — розпливчасто. Під це я можу зачепити й сусідні зони. Звузити область чи залишити як є?
Тьома відмахується — по старій звичці, як відмахувався ще місяць тому: git-то вже є:
— Та роби, чого ти. По ходу розберешся.
Рівно того, від чого його весь учорашній день відучав Льоха. Сашко не заперечує і починає працювати. Лагодить нарахування. А під «щоб усе було красиво» — лізе причісувати сусідню зону, лідерборд, який чіпати ніхто не просив.
Але Тьома не поспішає приймати всі правки. Він робить те, заради чого зранку й збирав увесь сейф, — перед тим, як прийняти, відкриває перегляд змін:
/diff
І звіряє очима: усе тут із задачі?
reward-flow.js
+ const reward = base * multiplier; // це, по суті, і є нарахування
leaderboard.js
+ sortByScore(players); // ← а це звідки? Лідерборд я не просив чіпати
Нарахування — по ділу. Але знизу, у leaderboard.js, — чужий рядок. Тьома на мить хмуриться і сам згадує Санине запитання.
— Сашко ж попереджав, — доходить до нього вголос. — «Красиво» — це й був лідерборд. Він спитав, а я відмахнувся.
Не Сашко накоїв. Сашко якраз чесно уточнив. Накоїло розпливчасте формулювання — рівно те, про що Льоха місяць товк. Прохід кривий, цей прохід не беремо. Добре, що глянув /diff до прийняття, а не влив навмання.
3. Крок 3–4. Скидання до чистої точки та фіксація комітом
Тьома не починає чистити все руками, рядок за рядком. Якщо прохід кривий — скидає гілку до останньої зафіксованої точки, до тієї чистої, що він поставив зранку. Просить словами:
Скинь гілку до останньої зафіксованої точки, почнемо заново.
І тут Сашко, не чекаючи відмашки, лізе сам:
— Стоп, для протоколу. Ти просиш git reset --hard — він зносить незафіксоване без запиту, повернути буде не можна. Усе, що я наменяв і не закомітив, щезне. Тобі ж це й треба?
— Саме це й треба, — киває Тьома. — Знось.
— Прийнято. Ще один нюанс: якщо я по ходу створив зовсім новий файл, якого git ще не бачив, — скидання його не зачепить, він так і лишиться лежати. Не лякайся, потім приберемо.
● git reset --hard HEAD
HEAD тепер на a1b2c3d — робочий портал до правок
Термінал написав рівно те, чого він чекав: гілка стоїть на точці «робочий портал до правок». А отже, на диску зараз має лежати чистий стан — правильне нарахування й зайвий хвіст у лідерборді стерто однією операцією, файли повернулися до стану, який був до Сашка. Має. Перевірити б.
І тут, за секунду до того як глянути на результат, його дряпає спогад про ту ніч. Він же вже бив по кнопці скасування — був певен, що врятує, — а вона не дотягнулася. Агент уже відпрацював скидання, а Тьома зволікає відкривати портал, і в животі короткий холодок: а раптом і ця штука так само? А раптом гляну зараз — а там і досі крива робота.
Глянув.
Чисто. Жодного сліду. Сусідня зона, яку Сашко зачепив, — на місці, ціла. Усе сміття, усе, що він навернув, — як корова язиком злизала. Не «майже прибрано», не «наче вичищено». Ніби Сашко сюди взагалі не заходив.
— Опа, — вголос каже Тьома порожній кімнаті. І ще раз, тихіше: — Опа.
Одна команда. Секунда. Ось саме цього йому тієї ночі й не вистачило. Тоді він годинами виколупував незворотне руками — а відмотувати було нікуди, жодної точки позаду. А зараз точка є, і відкат до неї — не подвиг, не археологія, не «ну наче памʼятаю, як було». Спокійно ткнув — і повернувся. Доросла версія тієї самої кнопки, по якій він бив тієї ночі даремно. Тільки ця дотягнулася.
Тепер чистовий прохід. І цього разу Тьома формулює інакше — вузько, точно, як навчено:
— Сашку, тільки reward-flow, тільки нарахування. Лідерборд і сусідні зони не чіпай взагалі.
— Оце вже інша розмова, — відгукується Сашко. — Межі зрозумілі, гадати не буду.
Проходить як треба. Тьома знову дивиться /diff — тільки reward-flow.js, нічого зайвого. Приймає. І щоб закріпити добрий стан, просить зафіксувати точку:
Зафіксуй правку: нарахування в reward-flow.
● git commit -m "fix: нарахування в reward-flow"
[fix-reward e4f5g6h] fix: нарахування в reward-flow
Тепер на диску, в історії проєкту, лежить нова чесна точка — та, до якої завжди можна повернутися, хоч після закритої сесії, хоч через тиждень. main увесь цей час залишався чистим: уся помилка прожила й зникла всередині гілки, не долетівши до робочого порталу й на секунду.
4. Контур зворотності та перевірка
Тьома записує в EVIDENCE_LOG, що вийшло за день. Льоха, все так само впівголоса, зазирає через плече.
— Дивись-но, — відзначає він. — Раніше ти сюди що заносив? Тільки перемоги: ось це запрацювало. А сьогодні в тебе тут увесь провал розкладено по поличках.
— Ну так, — Тьома проглядає свій запис. — Ось гілка fix-reward і чиста точка до правок. Ось кривий прохід, де Сашко зачепив зайве, і /diff, який це зловив. Ось скидання — криве стерто. Ось коміт вдалого проходу. І main, який увесь день не здригнувся.
— Ось саме. — Льоха трохи пожвавлюється. — Уперше записано не лише успіх, а й безпечний провал: як прохід зірвався і як проєкт це пережив без жодної подряпини. Та зворотність, яку я зранку змушував тебе доводити ще на папері, — ось вона, підтверджена ділом. Давай тепер швидко звіримося, чи все зібрав. Відповідай.
Він проговорює по пунктах, як контрольний список:
— Робота йшла в гілці fix-reward, а не прямо на main?
— Так.
— Перед прийняттям дивився /diff, що агент наменяв?
— Дивився, на тому й упіймав зайве.
— Кривий прохід відкотив скиданням гілки, а не виколупував руками?
— Скиданням. Однією операцією.
— Чистовий зафіксував комітом, точка стоїть? main увесь цикл недоторканний? І git ганяв сам агент, ти команди руками не друкував?
— Стоїть. Недоторканний. Жодної команди не набрав руками, — Тьома загинає пальці. — Усе зійшлося.
— Ну от, — киває Льоха. — Зібрав як треба. Правку прийнято через гілку й відкат, криве зникло без хірургії, main чистий.
Тьома відкидається, видихає. Ні феєрверка в грудях, ні азарту, як від нової іграшки, — щось рівне, важке, ніби вперше встав на тверде.
— Сашку, — каже він у чат. — Гілку під наступну задачу одразу заводити?
— Заводити, — відповідає Сашко. — Я готовий пробувати.
— Ну й пробуй. — Тьома посміхається, дивлячись на чистий портал. — Тепер-то можна. Не тому, що ти порозумнішав — ти той самий. А тому, що я порозумнішав, і під ногами зʼявилася підлога. Упаду — піднімуся.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ