JavaRush /Курсы /Claude Code SELF /Откат через git на практике

Откат через git на практике

Claude Code SELF
13 уровень , 4 лекция
Открыта

1. Шаг 1. Уводим работу в ветку

Лёха ушёл, Олег у себя. Сейф собран — Тёма проживает его сам, начисто, на той правке reward-flow, которую хотел внести с утра. Первым делом — увести работу в сторону от main. Тёма поворачивается к Сане, но на секунду тормозит: как там ветку-то назвать правильно?

— Сань, я хочу отдельную ветку под правку. Назвать как — есть разница?

— Разницы для git нет, — отвечает Саня ровно. — Но по-хорошему имя должно говорить, что за работа. fix-reward понятнее, чем test123 — через неделю сам вспомнишь. Завести?

— Заводи, fix-reward. И работай только в ней, main не трогай.

● git checkout -b fix-reward
  Switched to a new branch '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 is now at 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 чист.

Тёма откидывается, выдыхает. Ни фейерверка в груди, ни азарта, как от новой игрушки, — что-то ровное, тяжёлое, будто впервые встал на твёрдое.

— Сань, — говорит он в чат. — Ветку под следующую задачу сразу заводить?

— Заводить, — отвечает Саня. — Я готов пробовать.

— Ну и пробуй. — Тёма усмехается, глядя на чистый портал. — Теперь-то можно. Не потому что ты поумнел — ты прежний. А потому что я - поумнел и подо мной пол появился. Упаду — поднимусь.

1
Задача
Claude code, 13 уровень, 4 лекция
Недоступна
Терминальный поиск risk markers в конфиге и внешнем тексте
Терминальный поиск risk markers в конфиге и внешнем тексте
1
Задача
Claude code, 13 уровень, 4 лекция
Недоступна
Harden конфигурации PR-tools
Harden конфигурации PR-tools
1
Опрос
MCP в Claude Code, 13 уровень, 4 лекция
Недоступен
MCP в Claude Code
MCP в Claude Code
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ