Источник: Nuances of Programming
В этой статье мы рассмотрим два метода Git для отладки ошибок в базе кода — blame и bisect. С помощью Git blame описываются детали изменения каждой строки в файле, а bisect выполняет бинарный поиск по коммитам. Blame и bisect помогают устранять ошибки в больших базах кода с помощью обнаружения корневого коммита, приводящего к возникновению проблемы.
Подготовка файлов для отладки
Чтобы продемонстрировать функции отладки Git, мы будем использовать репозиторий на GitHub для запуска команд и воспроизведения результатов. Чтобы клонировать репозиторий, выполните следующую команду:
git clone https://github.com/sdaityari/my_git_project/
После завершения процесса клонирования измените активную директорию на клонированную папку.
cd my_git_project
ls -al
Теперь рассмотрим файлы в репозитории.
Чтобы проверить историю репозитория, выполните команду git log с опцией --oneline.
git log --oneline
Команда git log выводит историю проекта.
5199b4e — это коммит, приводящий к возникновению ошибки в файле sum.py. Файл содержит простую функцию, написанную на Python, которая складывает два числа.
В этом руководстве мы рассмотрим оба метода Git для отладки ошибок в коде. Начнем с Git blame.
Отладка через историю файлов
Зная исходный файл, приводящий к ошибке, можно использовать команду blame, чтобы получить коммит, который внес изменение. Как было сказано выше, ошибка была внесена в файл sum.py, поэтому запускаем команду blame в этом файле.
git blame sum.py
Вывод команды blame выглядит следующим образом:
Команда добавляет к каждой строке файла префикс хэша, автора и времени коммита. Обратите внимание, что ошибка находится в шестой строке файла, в которой к переменной b добавляется ноль вместо переменной a. Команда blame выводит достаточное количество данных, чтобы узнать, что коммит с хэшем
Обратите внимание, что единственным изменением в этом коммите была рассматриваемая строка. После обнуления коммита, в котором были внесены изменения, и изменений, внесенных в этот коммит, можно приступать к исправлению ошибки.
Отладка через бинарный поиск
Команда Git blame используется тогда, когда известен файл, в который было внесено изменение. Представьте сценарий, в котором виден результат ошибки, однако не известно, какая часть кода приводит к ней! В таких случаях на помощь приходит Git bisect.
Для начала в истории нужно определить коммит, в котором отсутствовала ошибка, то есть, «хороший» коммит. Цель процесса bisect состоит в том, чтобы найти коммит между этим «хорошим» коммитом и текущим «плохим» коммитом, который привел к возникновению ошибки. При инициировании процесса Git bisect запускается мастер, а репозиторий переходит во временный режим. На каждом этапе мастер изменяет состояние репозитория на промежуточный коммит и спрашивает, присутствует ли ошибка. Процесс продолжается до выявления первого «плохого» коммита.
Начнем с мастера bisect.
git bisect start
Затем нужно указать хорошие и плохие коммиты для запуска мастера. Выбираем первый коммит 8dd76fc в истории репозитория в качестве хорошего коммита.
git bisect good 8dd76fc
Поскольку последний коммит содержит ошибку, пометим его как плохой коммит.
git bisect bad c76ee85
После передачи хороших и плохих коммитов мастер спросит, существует ли ошибка до сих пор, изменив состояние репозитория.
Bisecting: 9 revisions left to test after this (roughly 3 steps)
[cafb55dde0af6e3ae300c1ba5e68a41fd49f7362] Merge commit '5ef655a4caf8'
Обратите внимание, что у нас есть девять коммитов, следовательно, потребуется примерно три шага (так как 2, возведенное в степень 3, равно 8, что очень близко к 9). При наличии тысячи коммитов потребовалось бы около десяти шагов (так как это процесс бинарного поиска).
На каждом шаге нужно проверять наличие ошибки и передавать либо git bisect good, либо git bisect bad.5199b4e1 привнес эту ошибку в код.
Для вывода списка изменений в коммите 5199b4e1 запустите команду git show.
git show 5199b4e1
Команды git show выводит список изменений в коммите.
братите внимание, что единственным изменением в этом коммите была рассматриваемая строка. После обнуления коммита, в котором были внесены изменения, и изменений, внесенных в этот коммит, можно приступать к исправлению ошибки.
Отладка через бинарный поиск
Команда Git blame используется тогда, когда известен файл, в который было внесено изменение. Представьте сценарий, в котором виден результат ошибки, однако не известно, какая часть кода приводит к ней! В таких случаях на помощь приходит Git bisect.
Для начала в истории нужно определить коммит, в котором отсутствовала ошибка, то есть, «хороший» коммит. Цель процесса bisect состоит в том, чтобы найти коммит между этим «хорошим» коммитом и текущим «плохим» коммитом, который привел к возникновению ошибки. При инициировании процесса Git bisect запускается мастер, а репозиторий переходит во временный режим. На каждом этапе мастер изменяет состояние репозитория на промежуточный коммит и спрашивает, присутствует ли ошибка. Процесс продолжается до выявления первого «плохого» коммита.
Начнем с мастера bisect.
git bisect start
Затем нужно указать хорошие и плохие коммиты для запуска мастера. Выбираем первый коммит 8dd76fc в истории репозитория в качестве хорошего коммита.
git bisect good 8dd76fc
Поскольку последний коммит содержит ошибку, пометим его как плохой коммит.
git bisect bad c76ee85
После передачи хороших и плохих коммитов мастер спросит, существует ли ошибка до сих пор, изменив состояние репозитория.
Bisecting: 9 revisions left to test after this (roughly 3 steps)
[cafb55dde0af6e3ae300c1ba5e68a41fd49f7362] Merge commit '5ef655a4caf8'
Обратите внимание, что у нас есть девять коммитов, следовательно, потребуется примерно три шага (так как 2, возведенное в степень 3, равно 8, что очень близко к 9). При наличии тысячи коммитов потребовалось бы около десяти шагов (так как это процесс бинарного поиска).
На каждом шаге нужно проверять наличие ошибки и передавать либо git bisect good, либо git bisect bad.
Коммит, вызвавший ошибку, успешно определен.
Чтобы выйти из мастера bisect, выполните команду reset.
git bisect reset
Автоматизация процесса Git Bisect
Чтобы исключить выполненную вручную часть процесса Git bisect, можно автоматизировать этот процесс с помощью модульных тестов. Вы можете написать сценарий, который определяет наличие ошибки. При наличии готового сценария запустите следующие команды:
git bisect run [command to run tests]
Если для запуска тестов вы используете команду python tests.py, то замените вторую команду на следующую:
git bisect run python tests.py
Заключение
В этом руководстве мы рассмотрели простой пример для объяснения двух динамических и полезных инструментов Git. Таким образом, если вы знаете исходный файл ошибки, то используйте команду Git blame, а если известно лишь поведение ошибки, то вам нужен процесс bisect.
Читайте также:
Читайте нас в телеграмме и vk
Перевод статьи Shaumik Daityar: Debugging with Git