git bisect: поиск бага

Бинарный поиск по истории коммитов для нахождения коммита, который первым ввёл регрессию или баг.

Зачем нужно

Когда баг обнаруживается в коде, который работал несколько недель назад, вручную проверять каждый из 200+ коммитов нереально. git bisect автоматизирует поиск: делит историю пополам, просит разработчика (или скрипт) пометить текущий коммит «хороший» или «плохой», и повторяет деление. За log2(N) шагов находит точный коммит — источник проблемы.

Где используется

  • Поиск коммита, сломавшего тест или конкретное поведение
  • Нахождение момента появления регрессии производительности
  • Автоматизированная диагностика с помощью тестового скрипта
  • Анализ: когда и с каким коммитом изменилось поведение

Основной контент

Ручной режим

# 1. Начать bisect
git bisect start

# 2. Пометить текущую версию как "плохую" (баг есть)
git bisect bad

# 3. Пометить версию, где баг точно отсутствовал
git bisect good v1.2.0
# или по хэшу:
git bisect good abc1234

# Git переключится на середину диапазона
# → Bisecting: 47 revisions left to test after this (roughly 6 steps)

# 4. Протестировать и пометить
git bisect bad    # баг есть
# или
git bisect good   # баг нет

# 5. Повторять до нахождения коммита
# Git сообщит:
# abc1234 is the first bad commit
# Author: Ivan <ivan@example.com>
# feat: добавить кэширование

# 6. Завершить bisect и вернуться к HEAD
git bisect reset

Автоматизированный режим

# Запустить скрипт автоматически
# Скрипт возвращает 0 = хорошо, не-0 = плохо

# Пример скрипта test.sh:
# #!/bin/bash
# npm test -- --testNamePattern="auth works"

git bisect start
git bisect bad HEAD
git bisect good v1.0.0

# Запустить автоматический поиск
git bisect run bash test.sh

# Git пройдёт все шаги сам и найдёт первый bad commit
git bisect reset

Дополнительные команды

# Пропустить коммит (если его нельзя протестировать — сломан билд)
git bisect skip

# Показать оставшиеся коммиты для проверки
git bisect visualize --oneline

# Посмотреть лог проделанного bisect
git bisect log

# Воспроизвести bisect из лога
git bisect replay bisect.log

Процесс поиска (бинарное дерево)

200 коммитов → ~8 шагов поиска:
200 → 100 → 50 → 25 → 12 → 6 → 3 → 1

Частые ошибки

  • Не сбросить bisect после завершения — репозиторий останется в промежуточном состоянии; всегда запускай git bisect reset
  • Пометить коммит неверно — ошибочное good/bad обнуляет прогресс; если сомневаешься — git bisect skip
  • Не учесть нестабильные тесты — случайно падающий тест даст неверный результат; убедись что тест детерминированный
  • Запустить bisect на ветке с большим числом merge-commit-ов — Git всё равно справится, но граф становится сложнее

Связанные темы

Ресурсы