Как найти проблемный коммит среди множества коммитов при случайных падениях приложения?
Что проверяют
Знаете ли вы git bisect и, главное, понимаете ли, почему «случайное» падение ломает бинарный поиск. Один ложный вердикт «good» уводит поиск в неверную половину, и найденный коммит окажется невиновным. Следом спрашивают, как сделать проверку надёжной и можно ли её автоматизировать.
Как отвечать
Сначала сузьте диапазон без git: в Crashlytics или Xcode Organizer видно, с какой версии и билда пошло падение, и тег последнего чистого релиза становится точкой «good».
Дальше бинарный поиск:
- старт:
git bisect start <bad> <good>, git переключает на середину диапазона. На тысячу коммитов уходит около десяти шагов, это log₂ n; - вердикт: после проверки
git bisect goodилиgit bisect bad. Коммит, который не собирается, пропускается черезgit bisect skip; - автоматизация:
git bisect run ./check.sh, где скрипт возвращает 0 для хорошего коммита, 125 для пропуска и другой код от 1 до 127 для плохого. Внутри удобно зватьxcodebuild testс-only-testingна воспроизводящий тест и гонять его многократно через-test-iterations; - финиш:
git bisect resetвозвращает на исходную ветку.
Для нестабильного падения ключевое правило: для «bad» хватает одного падения, а «good» ставится только после серии чистых прогонов, длину которой вы оцениваете по частоте краша. Если падает раз в десять запусков, пять успешных ничего не доказывают.
Добавьте, что случайность часто указывает на гонку данных или обращение к освобождённой памяти. Thread Sanitizer и Address Sanitizer в схеме нередко показывают причину быстрее бисекции.
Где спотыкаются
Отмечают коммит хорошим после одного успешного запуска. Для плавающего бага это почти гарантированно ложный вердикт.
Не учитывают окружение: между коммитами меняется Package.resolved или Podfile.lock, а в DerivedData остаётся старый кеш. Надёжнее чистая сборка на каждом шаге.
Останавливаются на найденном коммите и откатывают его. Коммит мог лишь проявить старую гонку, изменив тайминги, и откат спрячет проблему, а не устранит её.