Git bisect: как найти коммит, который сломал код
Команда git bisect ищет коммит, который сломал код, бинарным поиском по истории. Вы называете хороший и плохой коммиты, а git сам предлагает коммиты для проверки. Из 1000 коммитов хватит около десяти проверок.
Ручной поиск
git bisect start
git bisect bad # текущий коммит содержит ошибку
git bisect good v1.0.0 # этот тег или коммит работал верноGit переключит рабочую папку на коммит примерно в середине диапазона. Проверьте, воспроизводится ли ошибка, и сообщите результат:
git bisect good # на этом коммите ошибки нет
git bisect bad # на этом коммите ошибка есть
git bisect skip # коммит нельзя проверить, пропустить егоПовторяйте, пока git не напишет «is the first bad commit» и не покажет коммит. Когда поиск закончен, верните ветку на место:
git bisect resetАвтоматический поиск
Если ошибку можно проверить скриптом, поиск проходит без вашего участия. Скрипт должен завершаться с кодом 0 для хорошего коммита и с кодом от 1 до 127 для плохого:
cat > test.sh <<'EOF'
#!/bin/sh
grep -q "healthy" status.txt
EOF
chmod +x test.sh
git bisect start HEAD v1.0.0
git bisect run ./test.sh
git bisect resetКод выхода 125 говорит git пропустить текущий коммит: так отмечают коммиты, которые не собираются.
Посмотреть ход поиска
git bisect log # что вы уже отметили
git bisect visualize # открыть оставшийся диапазон в gitk
git bisect log > bisect.txt # сохранить журнал
git bisect replay bisect.txt # повторить его после ошибки в отметкахИспользовать другие слова вместо good и bad
Когда ищете не ошибку, а момент изменения поведения, смысл слов меняется:
git bisect start --term-old=slow --term-new=fast
git bisect fast # ускорение появилось здесьЧастые вопросы
Что делать, если я ошибся с отметкой good или bad?
Остановите поиск git bisect reset, а затем повторите его по сохранённому журналу, исправив неверную строку: git bisect replay bisect.txt.
Работает ли bisect с merge-коммитами?
Да, git учитывает всю историю, в том числе слияния. Если вы ищете именно в основной линии, добавьте --first-parent к git bisect start.