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 всё равно справится, но граф становится сложнее