# git bisect _Инструменты · GitLab Knowledge Base_ **TL;DR:** Бинарный поиск коммита, в котором появилась регрессия. Указываешь «здесь работало», «здесь сломалось», и за log(N) шагов Git находит точный SHA, где сломалось. `git bisect run` автоматизирует с помощью скрипта-проверяльщика. Bisect - самый недооценённый инструмент Git. На истории в десятки тысяч коммитов он находит источник регрессии за 10-15 шагов. ## Базовый ручной сценарий ```bash git bisect start git bisect bad # текущий - сломанный git bisect good v1.4 # знаем, что v1.4 работал ``` Git переключит на средний коммит. Ты тестируешь, отвечаешь: ```bash git bisect bad # баг есть git bisect good # бага нет ``` Git делит интервал пополам и переключает дальше. После `log2(N)` ответов: ``` a1b2c3d is the first bad commit commit a1b2c3d Author: ... Date: ... refactor: extract calculator class ``` По окончании: ```bash git bisect reset # вернуть HEAD на ветку, с которой начинали ``` ## Автоматический режим: bisect run Если есть скрипт-проверяльщик - Git делает всё сам. ```bash git bisect start git bisect bad git bisect good v1.4 git bisect run ./check.sh ``` Контракт скрипта: - `exit 0` - коммит good (тест прошёл) - `exit 1..124, 126..127` - коммит bad (тест упал) - `exit 125` - пропустить коммит (не удалось проверить) - другие коды - фатальная ошибка, bisect остановится Pytest и большинство тестовых фреймворков подходят напрямую (возвращают 0/1): ```bash git bisect run pytest tests/test_login.py::test_password_reset ``` ## Полезные команды во время bisect ```bash git bisect log # лог сессии bisect git bisect visualize # показать оставшийся интервал коммитов git bisect skip # пропустить текущий (не собирается / нерелевантный) git bisect reset # выйти и вернуться на исходную ветку git bisect replay # повторить сессию из сохранённого лога ``` ## Произвольные термины Если «good/bad» не подходит (ищешь когда фича *появилась*): ```bash git bisect start --term-old=missing --term-new=present git bisect present git bisect missing v1.0 ``` ## Подводные камни - **Промежуточные коммиты не собираются.** Bisect требует, чтобы каждый шаг можно было проверить. Если коммиты атомарны (см. [atomic-commit](/courses/git/kb/atomic-commit.md)) - всё ок. Если в истории мусор - `bisect skip` или `exit 125` в скрипте. - **Перемежающаяся регрессия.** Если баг возник, исчез, возник снова - bisect найдёт какую-то границу, но не первую. Лечится точностью теста. - **Внешние зависимости.** Если результат зависит от версии пакета, обнови зависимости в скрипте перед тестом - иначе bisect ловит окружение, а не коммит. ## Команды ```bash git bisect start && git bisect bad && git bisect good v1.0 ``` Начать бинарный поиск регрессии ```bash git bisect run ./test.sh ``` Запустить автоматический bisect со скриптом ```bash git bisect skip ``` Пропустить коммит, который не получается протестировать ```bash git bisect reset ``` Закончить bisect, вернуться на исходную ветку ## См. также - [git blame](/courses/git/kb/blame.md) - [git log](/courses/git/kb/log.md) - [git reflog](/courses/git/kb/reflog.md)