Как git может помочь с поиском источников багов в коде

Большое количество метаданных, хранящихся в git, и встроенные способы получения отчетов по ним дает некоторые инструменты для поиска источников тех или иных багов в коде.

Случай 1: Нахождение места поломки

Вернувшись после двухнедельного отпуска Вы обнаруживаете, что функционал который превосходно работал до вашего ухода, теперь работает с ошибками. За неделю было внесено большое количество изменений. Беглый просмотр изменений, в классах проблемного функционала, ничего не дал (изменений слишком много, либо не содержат явных ошибок). Unit-тесты проходят.

Тут git дает нам возможность за относительно небольшое время выяснить, в какой момент и по какой причине начала проявляться ошибка.

Для этого в git совсем недавно появился механизм git bisect, позволяющий двоичным поиском пройтись по диапазону изменений и найти место, в котором появилась определенная проблема.

Шаг 1: начинаем bisect

Для начала, нужно найти последний известный коммит, на котором все еще было хорошо, а так же первый известный коммит, на котором уже все плохо.

В данном случае, хороший коммит — коммит, который мы последним сделали перед уходом в отпуск и на котором ещё не было проблемы. Плохой коммит — коммит, на котором мы обнаружили проблему.

Затем мы запускаем git bisect

Если текущая версия и есть «bad commit», то можно не указывать коммит явно в git bisect bad.

После выполнения всех этих комманд, git перенесет нас на правки, которые были ровно между этими двумя коммитами.

Нас ждёт примерно следующий вывод:

Шаг 2: проверяем конкретную версию

Следующим шагом, нам нужно определить, повторяется ли проблема в текущей версии.

Шаг 3: переходим к следующей версии

Если проблема не повторяется, то выполняем

иначе, если проблема есть, выполняем

После выполнения одной из этих команд, git перенесет нас на следующий коммит, где мы должны будем повторить то же самое, начиная с шага 2, до тех пор пока git не сообщит нам, что мы закончили поиск.

Шаг 4: завершаем поиск

После того как мы нашли нужный коммит, мы должны выполнить следующую команду:

Эта команда сбросит состояние git bisect и перенесет нас на первый коммит, на котором начала воспроизводиться проблема.

Теперь мы можем изучить этот коммит для нахождения причины ошибки.

Документация по git bisect

Случай 2: Нахождение места внесения изменений

Мы нашли в коде участок, который приводит к ошибке в нашем приложении. Допустим, мы хотим выяснить, почему эта ошибка вообще появилась в нашем коде.

Нам нужно выяснить в каком коммите появился этот код.

Для этого хорошо использовать git blame. Он показывает автора последних изменений той или иной строки файла, а так же коммит, в котором эти изменения произошли.

Обычно лучше использовать визуальные средства для просмотра blame. Такие есть в TortoiseGit, SourceTree, SmartGit и других оболочках над git. Я буду приводить код для работы в консоли, чтобы описать суть действий, которые нам нужно произвести, для достижения цели. Инструкции для конкретных инструментов можно найти в интернете.

Шаг 1: ищем предыдущие правки кода

Смотрим blame интересующего файла.

Для консольного git

myfolder/myfile.code — путь к нужному файлу из текущего каталога
-L 26,30 — необязательный параметр, говорящий о том, что нам нужно просмотреть только определенные строки (со 120 по 130 строку)
-n — необязательный флаг, включающий в вывод номер строки в предыдущей её версии (может пригодиться дальше)

[свернуть]

Шаг 2: проверяем эти ли правки привели к проблеме

Узнав коммит, на котором было сделано изменение, нам в первую очередь нужно проверить, точно ли в этом изменении были изменены ошибочные правки. Может случиться так, что кто-то проводил рефакторинг и переместил этот код из другого места, изменил уровень табуляции или убрал пробелы в конце строки.

Если мы все таки нашли нужные изменения переходим к шагу 4.

Шаг 3: ищем более ранние правки кода

Если найденный коммит всего лишь вносил незначительные изменения в нужные строки, но ошибка была раньше, нам нужно сделать blame версии, предшествующей данному коммиту.

Для консольного git

В предыдущем выводе git blame мы получили примерно следующий вывод для каждой строки

26 — это номер строки в текущей версии, 24 — номер этой же строки в предыдущей версии, 87796b38 — hash предыдущей версии.

Допустим, в предыдущей версии эти строки шли в том же порядке, тогда нам нужно выполнить команду следующего вида:

где вместо 87796b38 нужно вписать hash коммита,полученного из предыдущего вывода, а вместо 24,26 — строки, изменения которых мы хотим найти.

[свернуть]

Переходим к шагу 2.

Шаг 4: разбираемся что произошло

Мы выяснили в каком коммите были внесены эти нехорошие изменения. Это дает нам возможность узнать зачем они были внесены, если не из коммита, то от автора изменений. Возможно внесение этих правок имело вескую причину.

Документация по git blame

Поделиться

Оставить ответ