Большое количество метаданных, хранящихся в git, и встроенные способы получения отчетов по ним дает некоторые инструменты для поиска источников тех или иных багов в коде.
Случай 1: Нахождение места поломки
Вернувшись после двухнедельного отпуска Вы обнаруживаете, что функционал который превосходно работал до вашего ухода, теперь работает с ошибками. За неделю было внесено большое количество изменений. Беглый просмотр изменений, в классах проблемного функционала, ничего не дал (изменений слишком много, либо не содержат явных ошибок). Unit-тесты проходят.
Тут git дает нам возможность за относительно небольшое время выяснить, в какой момент и по какой причине начала проявляться ошибка.
Для этого в git совсем недавно появился механизм git bisect, позволяющий двоичным поиском пройтись по диапазону изменений и найти место, в котором появилась определенная проблема.
Шаг 1: начинаем bisect
Для начала, нужно найти последний известный коммит, на котором все еще было хорошо, а так же первый известный коммит, на котором уже все плохо.
В данном случае, хороший коммит — коммит, который мы последним сделали перед уходом в отпуск и на котором ещё не было проблемы. Плохой коммит — коммит, на котором мы обнаружили проблему.
Затем мы запускаем git bisect
1 2 3 |
git bisect start git bisect bad [bad commit] git bisect good [good commit] |
Если текущая версия и есть “bad commit”, то можно не указывать коммит явно в git bisect bad.
После выполнения всех этих комманд, git перенесет нас на правки, которые были ровно между этими двумя коммитами.
Нас ждёт примерно следующий вывод:
1 |
Bisecting: 337 revisions left to test after this (roughly 9 steps) |
Шаг 2: проверяем конкретную версию
Следующим шагом, нам нужно определить, повторяется ли проблема в текущей версии.
Шаг 3: переходим к следующей версии
Если проблема не повторяется, то выполняем
1 |
git bisect good |
иначе, если проблема есть, выполняем
1 |
git bisect bad |
После выполнения одной из этих команд, git перенесет нас на следующий коммит, где мы должны будем повторить то же самое, начиная с шага 2, до тех пор пока git не сообщит нам, что мы закончили поиск.
Шаг 4: завершаем поиск
После того как мы нашли нужный коммит, мы должны выполнить следующую команду:
1 |
git bisect reset bisect/bad |
Эта команда сбросит состояние git bisect и перенесет нас на первый коммит, на котором начала воспроизводиться проблема.
Теперь мы можем изучить этот коммит для нахождения причины ошибки.
Документация по git bisect
Случай 2: Нахождение места внесения изменений
Мы нашли в коде участок, который приводит к ошибке в нашем приложении. Допустим, мы хотим выяснить, почему эта ошибка вообще появилась в нашем коде.
Нам нужно выяснить в каком коммите появился этот код.
Для этого хорошо использовать git blame. Он показывает автора последних изменений той или иной строки файла, а так же коммит, в котором эти изменения произошли.
Обычно лучше использовать визуальные средства для просмотра blame. Такие есть в TortoiseGit, SourceTree, SmartGit и других оболочках над git. Я буду приводить код для работы в консоли, чтобы описать суть действий, которые нам нужно произвести, для достижения цели. Инструкции для конкретных инструментов можно найти в интернете.
Шаг 1: ищем предыдущие правки кода
Смотрим blame интересующего файла.
1 |
git blame myfolder/myfile.code -L 26,30 -n |
myfolder/myfile.code – путь к нужному файлу из текущего каталога
-L 26,30 – необязательный параметр, говорящий о том, что нам нужно просмотреть только определенные строки (со 120 по 130 строку)
-n – необязательный флаг, включающий в вывод номер строки в предыдущей её версии (может пригодиться дальше)
Шаг 2: проверяем эти ли правки привели к проблеме
Узнав коммит, на котором было сделано изменение, нам в первую очередь нужно проверить, точно ли в этом изменении были изменены ошибочные правки. Может случиться так, что кто-то проводил рефакторинг и переместил этот код из другого места, изменил уровень табуляции или убрал пробелы в конце строки.
Если мы все таки нашли нужные изменения переходим к шагу 4.
Шаг 3: ищем более ранние правки кода
Если найденный коммит всего лишь вносил незначительные изменения в нужные строки, но ошибка была раньше, нам нужно сделать blame версии, предшествующей данному коммиту.
В предыдущем выводе git blame мы получили примерно следующий вывод для каждой строки
1 |
</code>87796b38 24 (Name Surname 2016-03-25 12:10:28 +0300 26) SomeCodeInFile(); |
26 – это номер строки в текущей версии, 24 – номер этой же строки в предыдущей версии, 87796b38 – hash предыдущей версии.
Допустим, в предыдущей версии эти строки шли в том же порядке, тогда нам нужно выполнить команду следующего вида:
1 |
git blame myfolder/myfile.code -L 24,28 -n </code>87796b38^1 |
где вместо 87796b38 нужно вписать hash коммита,полученного из предыдущего вывода, а вместо 24,26 – строки, изменения которых мы хотим найти.
Переходим к шагу 2.
Шаг 4: разбираемся что произошло
Мы выяснили в каком коммите были внесены эти нехорошие изменения. Это дает нам возможность узнать зачем они были внесены, если не из коммита, то от автора изменений. Возможно внесение этих правок имело вескую причину.
Документация по git blame
Leave a Reply
You must be logged in to post a comment.