Метод git bisect
– мощный инструмент для поиска изменения, вызвавшего баг в коде: с его помощью разработчику удалось быстро локализовать проблему, просмотрев всего 11 коммитов вместо изначальных 2088.
Задача: найти конкретный коммит, который вызвал регрессионную ошибку в проекте
Исходные данные:
- Ошибка была зарегистрирована 21 октября. Она находится в текущей версии на ветке
main
. - Ошибка отсутствует в более ранней версии, которая была выделена в отдельную ветку
release-5.7.0
. - Ветку
release-5.7.0
создали 2 месяца назад, а с тех пор в ветке main было сделано много изменений – баг может находиться в любом из нескольких тысяч коммитов, которые невозможно быстро просмотреть.
Как найти ошибку
Чтобы понять, в каком конкретном изменении появилась ошибка, нужно:
- Найти точку в истории проекта, где код еще работал корректно.
- Использовать инструмент
git bisect
, чтобы сократить поиск до минимального числа проверок.
Шаг 1: Находим «хороший» и «плохой» коммиты
Так как в ветке release-5.7.0
ошибки нет, значит, баг появился в ветке main
после того, как была создана ветка release-5.7.0
. Для определения общего предка (начальной точки ветвления) используется команда:
git merge-base main release-5.7.0
Эта команда найдет общего предка двух веток, то есть коммит, с которого ветка release-5.7.0
была выделена из ветки main
. Этот коммит (назовем его commit0001
для краткости) будем считать «хорошим» – в нем ошибки еще не было.
Ошибка была зарегистрирована 21 октября. Значит, нужно найти коммит, который точно содержит баг, сделанный до этой даты. Для этого используется команда:
git log --before="2024-10-21" -n 1 main
Этот коммит будем считать «плохим» – баг в нем уже есть. Для простоты назовем его commit9999
.
Шаг 2: Определяем количество коммитов между «хорошим» и «плохим»
Чтобы понять, сколько коммитов нужно проверить между этими двумя точками, используем команду:
git rev-list --count commit0001..commit9999
Результат: между этими двумя коммитами оказалось 2088 изменений – слишком много, чтобы просматривать вручную.
Шаг 3: Используем бинарный поиск git bisect
Инструмент git bisect
помогает быстро найти коммит, который вызвал ошибку, применяя алгоритм бинарного поиска. Вместо проверки всех 2088 коммитов вручную, нужно будет проверить всего 10-11 шагов.
Инициализируем процесс поиска, указав «хороший» и «плохой» коммиты:
git bisect start
git bisect good commit0001
git bisect bad commit9999
После этого Git автоматически выбирает коммит посередине между «хорошим» и «плохим» . Например, он может сообщить что-то вроде:
Bisecting: 1044 revisions left to test after this (roughly 10 steps)
Теперь нужно проверить выбранный коммит:
- Если баг присутствует, вводите
git bisect bad
- Если бага нет –
git bisect good
Git снова выбирает коммит в середине оставшегося диапазона. Например:
Bisecting: 522 revisions left to test after this (roughly 9 steps)
Вы продолжаете тестировать выбранные коммиты, каждый раз указывая good
или bad
. При этом диапазон подозреваемых коммитов уменьшается в два раза на каждом шаге. После нескольких шагов (не более 10-11 для 2088 коммитов) git bisect
сообщает, что нашел первый коммит, в котором появился баг:
commit1234 is the first bad commit
commit commit1234
Author: Some Person <somebody@example.com>
Date: Wed Oct 16 13:43:01 2024 -0400
[commit message]
В заключение
Метод git bisect
особенно полезен в больших проектах с частыми коммитами – он значительно экономит время и ускоряет поиск проблемных изменений. Возьмите на заметку!
А какие еще инструменты Git вы используете для отладки кода? Поделитесь своим опытом в комментариях!
Комментарии