Как разобрать чужую ошибку: метод коммитсов
Найти в открытом проекте настоящую историю поломки, восстановить ход мысли по написанному и закончить проверкой своего кода
miki/kak-razobrat-chuzhuyu-oshibku-metod-kommitsov · v4
Найти в открытом проекте настоящую историю поломки, восстановить ход мысли по написанному и закончить проверкой своего кода
Коммитс (англ. commitics) — документальный разбор настоящей ошибки в открытом проекте, собранный из коммитов, PR и переписки.
Каждый заход даёт два результата: публичный разбор с цитатами и ссылками — и внутренний вывод про свой код. Второй обязателен: разбор без него — чтение, а не работа.
Жанр развлекательный, а не учебный. Читатель пришёл за историей, а не за уроком. Польза извлекается сама, потому что история настоящая.
- Кадр — это коммит, PR или реплика. У каждого есть дата, автор и одно событие. «29 июня 2022 приезжает коммит
Add a few strategies» — кадр. «Разработчики добавили стратегии» — пересказ. - Даты вслух. Не «позже», а «через год и четыре месяца». Промежуток — половина драматургии.
- Название коммита — реплика персонажа. Их не пересказывают, их приводят.
- Одно событие — один абзац.
- Последствие показывается, а не называется. Не «некорректный расчёт», а «кнопка ‘убрать скидку’ выдавала максимальную».
- Пуант в конце. Заголовок интригует, но не раскрывает.
- Тестов и опросов в конце нет. Вопрос с четырьмя вариантами превращает историю в проверочную работу. Вывод — да, экзамен — нет.
Главное — люди, а не код. Читателю интересно место, где работают программисты: команда, ревью, спор, решение, которое кому-то пришлось защищать. Код — повод, а не содержание.
Что искать в первую очередь:
- ревью с возражением — кто-то сказал «так нельзя» и оказался прав (или не оказался, и это ещё интереснее);
- PR, который защищали — автор отвечает на замечания, меняет подход, спорит с мейнтейнером;
- откат, который пришлось объяснять — решение прожило и было отменено;
- мейнтейнер против контрибьютора, команда против сроков, двое несогласных и третий, который принял решение;
- честно названная цена: «мы знаем, что это плохо, и вот почему оставили».
Проект с командой ценнее одиночного репозитория. Не из снобизма: где есть процесс, там есть переписка, а где есть переписка — есть ход мысли. В репо одного человека решение принимается молча, и восстанавливать нечего.
Сгенерированное допустимо, но это не цель. У генерации не бывает ни спора, ни второй стороны, ни человека, который за неё отвечает.
Свой код — короткий хвост, а не половина текста. Проверка обязательна — она делает работу работой, а не чтением. Но читателю она неинтересна: абзац-два, конкретно. Всё остальное место принадлежит чужой истории и людям в ней.
Имя ставится там, где человек что-то сделал или сказал. Автор цитаты, автор коммита, автор починки. Это и точность, и уважение.
«Кто сломал» — обычно неизвестно и почти всегда неважно. git blame показывает последнего, кто трогал строку. Герой разбора — тот, кто нашёл; злодей — обстоятельства.
Мотивы не домысливаются. «Разработчик, вероятно, торопился» — это выдумка про живого человека под его именем. Не написано — значит неизвестно.
Юмор про положение, а не про людей. Смешное почти всегда в самой ситуации. Насмешка над автором и нечестна, и скучна.
Мы попадаем в разборы наравне. Если та же ошибка нашлась у нас — так и пишется, с тем же тоном. Это единственное, что делает остальное честным.
Как искать
На урезанном клоне поиск по содержимому коммитов не работает — а именно он находит, когда строка появилась и что было до неё.
git clone https://github.com/OWNER/REPO && cd REPO && git log -S "ключевое слово" --oneline- Репозиторий клонирован с полной историей
В названиях коммитов ищите «back to», «revert», «actually», «fix race», «properly». Самые ценные места — те, где решение приняли, пожили с ним и отменили.
git log --oneline -- путь/к/файлу- Найдена цепочка из двух и более событий, а не одиночный фикс
Описания PR и комментарии в задачах часто ценнее кода: там объясняют, почему НЕ сделали правильнее. Там же слова пострадавшего.
gh api repos/OWNER/REPO/issues/N/comments --jq '.[]|"\(.user.login) \(.created_at[0:10])\n\(.body)"'- Есть хотя бы одна дословная цитата со ссылкой
- К каждой цитате есть перевод рядом, а не вместо
В каждом пункте, где упоминается код: не «в таком-то файле», а permalink вида blob/<полный-sha>/путь#L574-L590. Ссылка кладётся в refs шага; в кадре с цитатой кода — рядом с цитатой.
gh api repos/OWNER/REPO/commits/main --jq .sha- Ни одной ссылки вида blob/main — везде полный SHA
- У каждой ссылки есть номер строки или диапазон
- Ссылка открыта и проверено, что там именно тот код, о котором речь
Цена почти всегда описана не в коде, а в разделе для пользователей про ошибки и ограничения — там она честнее.
- Цена решения найдена и процитирована словами самого проекта
Чем заканчивать
Греп, тест или правка. Если у вас всё хорошо — так и напишите, назвав конкретные места и почему они устойчивы.
- Названы конкретные файлы и строки, а не «у нас такого нет»
- Если нашлось — есть коммит или задача, а не намерение
Полчаса поисков без цепочки «сделали так → столкнулись с тем-то → починили этак → объяснили словами» — тема закрывается, берẻтся другая.
- Заход уложился в час вместе с проверкой своего кода
Переносится в любой проект как есть — подставьте тему.
Найди и разбери настоящую историю ошибки в открытом проекте по теме «ТЕМА» (например: очередь задач, списание бонусов, ограничение частоты, часовые пояса, загрузка файлов).
Где искать. Полный
git clone(не--filter=blob:none— на нёмgit log -Sумирает). Дальше:
git log -S "ключевое слово"— когда строка появилась и что было до;git log --oneline -- путь/к/файлу— искать откаты и переписывания: «back to», «revert», «actually», «fix race», «properly»;gh api repos/ВЛАДЕЛЕЦ/РЕПО/pulls/Nи…/issues/N/comments— описания и переписка. Часто ценнее кода: там объясняют, почему не сделали правильнее;- задача, на которую ссылается PR: там слова пострадавшего;
- документация проекта: там цена решения, описанная для пользователя.
Что считается хорошей находкой. Не «нашёл баг», а нашлась цепочка: кто-то сделал так → столкнулись с тем-то → починили этак → и объяснили словами почему.
И главное — в цепочке должны быть ЛЮДИ. Интересно место, где работают программисты: команда, ревью, спор, решение, которое кому-то пришлось защищать или отменять. Ищи в первую очередь возражение в ревью, PR, который автор отстаивал, откат, который объясняли, несогласие мейнтейнера с контрибьютором, честно названную цену («знаем, что плохо, оставили вот почему»). Проект с командой ценнее одиночного репозитория: где есть процесс, там есть переписка, а где переписка — там ход мысли. Сгенерированный код допустим как материал, но у генерации нет ни спора, ни второй стороны, ни человека, который за неё отвечает.
Что написать. Публичный разбор — и коротким хвостом внутренний вывод. Вывод обязан заканчиваться проверкой своего кода — грепом, тестом, правкой; если всё хорошо, так и напиши, назвав конкретные места и почему они устойчивы. Но это абзац-два, а не половина текста.
Ссылка на код — на СТРОКУ и по SHA. В каждом пункте, где упоминается код. Не «в
ScheduleComponent.tsx», аhttps://github.com/ВЛАДЕЛЕЦ/РЕПО/blob/<полный-sha>/путь/файл.ts#L574-L590. Ссылка на ветку (blob/main/…) не годится: через месяц строки уедут, и читатель откроет чужой код на том же номере — то есть соврẻт ровно там, где пошли проверять. SHA:git rev-parse HEADв клоне илиgh api repos/О/Р/commits/main --jq .sha; на сайте GitHub — клавишаy. В шаге списка ссылка кладётся вrefs, а не в текст.Правила точности. Цитаты дословные и со ссылкой, перевод рядом с оригиналом. Имена — там, где человек что-то сказал или сделал. Мотивы не домысливать: не написано — значит неизвестно. «Кто сломал» по
git blameне устанавливается — он показывает, кто трогал строку последним.Остановка. Полчаса поисков без цепочки — тема закрывается, берётся другая. Разборы делаются рядом с разработкой, а не вместо неё.
Related lists
graphile-worker: очередь на Postgres, замеры в комментариях и настройка, не пережившая полутора лет
Medusa: защита от повтора отказывает там, где можно было ответить, и пропускает там, где повтор стоит денег
Saleor: три человека за три года просят денег без копеек, потому что таких монет нет в обращении
Better Auth: ограничение частоты считалось от последнего запроса, включая отклонённые, — и разблокировка не наступала никогда
Medusa: кнопка «убрать скидку» выдавала максимальную, потому что ноль в JavaScript ложный
Как Cal.com год чинил расписание, переходящее за полночь, и чем это кончилось
