git bisect Найти коммит, который вызвал сбой, не читая 500 строк лога

Обновлено

Прекращайте сканирование истории git для коммита, который сломал производство. git bisect проводит бинарный поиск в истории примерно за 9 шагов независимо от количества коммитов в диапазоне. Ниже приведена полная последовательность действий, реальная сессия с комментариями и возможные проблемы, на которые нужно обратить внимание.

git bisect: Найти повреждающий коммит без чтения 500 строк лога 1
Реклама · УДАЛИТЬ?

Вы отправили 50 коммитов за две недели. В какой-то момент что-то сломалось. Тест, который проходил три недели назад, теперь не проходит. git log --oneline показывает 200 строк, которые вы не хотите читать.

У вас есть варианты: смотреть на различия до тех пор, пока глаза не начнут кровоточить, git checkout делать случайные коммиты и проверять вручную, или использовать инструмент, который был в git с 2007 года и входит в состав каждой установки.

git bisect проводит двоичный поиск в истории коммитов. Вы отмечаете один коммит как неисправный, один как рабочий, и он выходит на коммиты между ними — каждый раз сокращая пространство поиска вдвое. Поиск виновника в 500 коммитов занимает около 9 шагов. Большинство разработчиков никогда его не используют.

Как это работает

Полный процесс начинается тремя командами:

git bisect start
git bisect bad                 # current state is broken
git bisect good v2.4.0         # last known-good tag or commit hash

Git выходит на коммит, находящийся на полпути между двумя точками. Вы проверяете, есть ли ошибка, и сообщаете результат:

git bisect good   # bug is NOT present here
# or
git bisect bad    # bug IS present here

Git сокращает диапазон и выбирает следующую середину. Повторяйте, пока он не скажет вам abc1234 is the first bad commit. Когда вы закончите:

git bisect reset  # returns you to your original branch

Нет особых флагов, нет конфигурации, нет плагинов. Работает на любом репозитории, на любой версии git, которую вы, вероятно, установили.

Реальная сессия bisect (аннотированная)

Вот полная сессия. Функция, возвращающая правильный JSON, начала возвращать null после недавних рефакторингов — в последних коммитах не было очевидного виновника:

$ git bisect start
$ git bisect bad HEAD              # current commit is broken
$ git bisect good 3f8a12b          # commit from 2 weeks ago, worked fine

Bisecting: 24 revisions left to test after this (roughly 5 steps)
[c9e41f0] Refactor: extract auth middleware

$ npm test -- --grep "parseResponse"   # ← run your check here
# FAIL
$ git bisect bad

Bisecting: 12 revisions left to test after this (roughly 4 steps)
[a77b2d1] Fix: update retry logic in fetch wrapper

$ npm test -- --grep "parseResponse"
# PASS
$ git bisect good

Bisecting: 6 revisions left to test after this (roughly 3 steps)
[91e0bc3] Refactor: consolidate response handlers

$ npm test -- --grep "parseResponse"
# FAIL
$ git bisect bad

Bisecting: 2 revisions left to test after this (roughly 2 steps)
[b44c19f] Chore: remove deprecated serialization helpers

$ npm test -- --grep "parseResponse"
# FAIL
$ git bisect bad

Bisecting: 1 revision left to test after this (roughly 1 step)
[8d3e77a] Fix: normalize response envelope for new API version

$ npm test -- --grep "parseResponse"
# PASS
$ git bisect good

91e0bc3e1f4d is the first bad commit
commit 91e0bc3e1f4d
Author: Dev <dev@example.com>
Date:   Mon Apr 14 11:23:07 2026

    Refactor: consolidate response handlers

 src/http/response.js | 14 +++---

$ git bisect reset   # ← always do this when done

5 шагов через диапазон из 50 коммитов. Коммит «объединение обработчиков ответов» тихо убрал вызов сериализации, на который что-то внизу зависело. Без bisect вы бы читали диффы в течение часа.

Автоматизация

Если вы можете выразить проверку в виде скрипта — выход 0 для хорошего, не нулевой для плохого — git bisect может работать полностью без участия человека:

git bisect start
git bisect bad HEAD
git bisect good v2.4.0
git bisect run npm test -- --grep "parseResponse"

Git выходит на каждую середину, запускает скрипт и сообщает первый неисправный коммит. Для тестов, которые выполняются менее чем за 10 секунд, это достаточно быстро, чтобы вы могли уйти и вернуться с ответом.

Семантика выходных кодов для запуска скрипта:

  • 0 — коммит хороший
  • 1–124 — коммит плохой
  • 125 — пропустить этот коммит (не компилируется, нельзя проверить)

Используйте 125 когда коммит не компилируется или инфраструктура тестов сломана в этот момент — bisect пропускает его и переходит к следующему кандидату.

Когда bisect превосходит git blame

git blame показывает, кто последний раз касался строки. Полезно, когда вы уже знаете, какая строка неверна. git bisect используется тогда, когда вы не знаете — когда симптом является поведенческим и причина может быть где угодно.

Используйте bisect тогда:

  • Вы можете воспроизвести регрессию, но не можете отследить её до конкретного файла
  • Поведение в производственной среде изменилось, но в недавних коммитах нет очевидного подозреваемого
  • «Это работало в v2.3, сломалось в v2.5» с 80+ коммитами между ними
  • Тест начал проходить нестабильно около определённой даты

Когда сравниваются выводы между двумя коммитами во время bisect, вставляются оба в инструмент сравнения текста часто быстрее, чем чтение унифицированных диффов в терминале — особенно когда вывод — это блок JSON или сериализованное значение.

Общие ошибки при работе

Не забывайте git bisect reset. Bisect выходит на коммиты в состоянии оторванного HEAD. Если вы переключаетесь на ветку в процессе сессии без сброса, состояние bisect станет устаревшим и вы будете ошеломлены. Всегда сбрасывайте после завершения, даже после того, как вы нашли ответ.

Слияния коммитов могут искажать диапазон. Если ваш диапазон включает ветку с долгосрочным функционалом, которая была включена, bisect может попасть в коммиты этой ветки в неочевидном порядке. Запустите git log --oneline --no-merges good..bad сначала, чтобы понять, что находится в диапазоне.

Воспроизводимость тестов — всё. Если ваша проверка нестабильна — зависящая от времени, среды или взаимодействующая с внешним сервисом — bisect даст вам плохие результаты. Убедитесь, что тест является детерминированным, прежде чем автоматизировать его.

Коммит, который идентифицируется bisect, указывает на изменение поведения, а не обязательно на местоположение бага. Иногда правильный рефакторинг раскрывает предыдущее предположение в другом месте. Рассматривайте результат как «начать читать здесь», а не как «откатить этот и всё будет хорошо».

Если вы регулярно отлаживаете историю git, на IO Tools есть bisect, blame, log и reflog на одной странице — стоит добавить в закладки для следующего раза, когда что-то необычное сломается. Шпаргалка по Git git bisect: Найти коммит, который сломал систему, не читая 500 строк лога 2

Хотите убрать рекламу? Откажитесь от рекламы сегодня

Установите наши расширения

Добавьте инструменты ввода-вывода в свой любимый браузер для мгновенного доступа и более быстрого поиска

в Расширение Chrome в Расширение края в Расширение Firefox в Расширение Opera

Табло результатов прибыло!

Табло результатов — это интересный способ следить за вашими играми, все данные хранятся в вашем браузере. Скоро появятся новые функции!

Реклама · УДАЛИТЬ?
Реклама · УДАЛИТЬ?
Реклама · УДАЛИТЬ?

новости с техническими моментами

Примите участие

Помогите нам продолжать предоставлять ценные бесплатные инструменты

Купи мне кофе
Реклама · УДАЛИТЬ?