git bisect что это

Git bisect. Ищем баги с помощью гита

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

Другой вариант, засесть и последовательно анализировать цепочку вызовов функций, отслеживать переменные в отладчике, разбираться во взаимосвязях отдельных частей системы. Способ тоже неплохой, но очень трудозатратный.

Вроде звучит все просто. Но проблема в том, что это годится, если в ветке 3 коммита, их и перебрать можно. А если 10? А если 50 или 100? Ну, например, ветка долгоживущая. Что теперь, по очереди всю сотню перебирать? А если бага в самом начале случилась? Двигаться с конца?

Тут вспоминаем, что мы вообще-то программисты и алгоритмы умеем. А еще вспоминаем игру, которой можно сильно удивить любого первоклассника. Мол, давай ты загадаешь число от 1 до 100, а я буду пытаться угадать. Я называю число, а ты говоришь, твое задуманное больше или меньше. И спорим, что за 7 попыток угадаю? За 7, а не за 100! Чудеса.

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

Давайте посмотрим на примере, как это работает.

Я взял наш проект интернет-магазина, создал новую ветку и накомитил туда 8 коммитов. Вот так это выглядит в PhpStorm

Коммиты сделаны от балды, но пронумерованы от 1 до 8. Это сделал, чтобы было удобнее смотреть, как git bisect делает свои переключения. Будем следить шаг за шагом.

Проверяем добавление товара в браузере, ага, бага осталась. Пишем в консоли, git bisect bad. То есть больше никаких хэшей не упоминаем, только говорим, плохой коммит или хороший. Дальше git bisect разберется за нас. Вот что происходит в консоли

Нас кинули на третий коммит. Чтобы убедиться, смотрим в PhpStorm

Давайте же посмотрим на этот третий коммит. Откроем git diff в PhpStorm и видим волшебный код

Да, я в функцию клика по кнопке «Добавить» просто написал alert(‘Error’) и return false. Не делайте так 🙂
Все, осталось убрать эти строчки и баг пофикшен.

Конечно, многое зависит от того, какой у вас будет искомый коммит. Если там изменений на 500 строк в 30 файлах, то искать сам баг будет непросто. Но все равно легче, когда знаем, что косяк именно в этом коммите. Кстати, это еще один аргумент в пользу того, чтобы делать коммиты как можно меньше. Маленькие коммиты легче читать и проще отлаживать. Но в любом случае, знание конкретного коммита облегчит поиск и исправление проблемы.

Вот и все. Такой он, git bisect, страшно звучит, но просто работает.

Источник

Дебаггинг с использованием git bisect

Перевод статьи «Debug your code using git bisect».

Несколько дней назад я впервые прочитал о git bisect в этом твите:

Я с первого взгляда понял, что это просто потрясающий инструмент. Прямо с main-страницы, где говорится:

«git-bisect — используй двоичный поиск, чтобы найти коммит, с которым в базу попал баг».

(Прим. перев.: слово «bisect» означает «делить пополам»).

В общем, это же именно то, что нам нужно в нашей ежедневной работе, правда? Занимаясь разработкой какой-нибудь фичи, мы часто оказываемся в ситуации, когда отдельный ее фрагмент сломан. Но он не должен быть сломан, ведь мы же не трогали никакой код, имеющий отношение к этому фрагменту (или забыли об этом — что более вероятно). Что мы делаем в таких случаях? Лично я проверяю отдельные коммиты, которые мне кажутся подозрительными, или изменения в файлах. Но чтобы сузить поиск, нужно приложить чертовски много усилий. Для автоматизации процесса мы можем использовать git bisect.

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

Для начала мы должны указать, какой коммит является «плохим» («bad»), т. е., как мы знаем, точно содержит баг. В большинстве случаев он там, где HEAD, но мы можем указать и другой — при помощи commit hash.

Затем нам нужно пометить «хороший» («good») коммит — тот, в котором этого бага точно нет и все работает прекрасно.

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

Читайте также:  какой международный документ регламентирует порядок рассмотрения происшествий на море

Фактически git bisect может быть использован для поиска коммита, изменившего любое свойство в проекте. Например, коммита с исправлением бага или коммита, после которого существенно улучшились показатели. Для подобного более широкого использования вместо терминов «good» и «bad» можно применять термины «old» и «new» («старый» и «новый»).

Как использовать git bisect?

Для начала нам нужно начать bisect-сессию и пометить хороший и плохой коммит, т. е., определить границы, в которых мы будем искать баг.

После этого процесс будет запущен автоматически. Git начнет делить ревизии надвое и загружать их для нас. Он будет проверять каждую ревизию (revision) и спрашивать нас, хороший это коммит или плохой. Чтобы вынести свой вердикт, нам нужно будет скомпилировать и протестировать код этой конкретной версии. Наш ответ будет выглядеть так:

Этот процесс продолжается итеративно: компиляция, тестирование, пометка коммита «плохим» или «хорошим» и переход на новый круг. В конечном итоге, когда у нас уже не останется ревизий для проверки, команда выведет описание первого «плохого» коммита.

Предположим, мы хотим найти коммит, который сломал фичу. Известно, что в промежутке между коммитами 8c054db и 5908ecf фича работала. Запустив сессию git bisect, мы указываем «хороший» и «плохой» коммит:

В своей консоли вы увидите нечто подобное:

Здесь я протестировал свой код, и оказалось, что он работает хорошо. Помечаем его как хороший:

Это приводит нас к следующему шагу:

По окончании bisect-сессии, то есть, когда вы успешно нашли баг, нужно очистить состояние bisect и вернутся к оригинальному HEAD. Для этого запускаем команду:

По умолчанию это вернет наше дерево к последнему подтвержденному коммиту перед запуском git bisect start. Но мы можем вернуться и к другому коммиту, если добавить опциональный аргумент:

Можно ли автоматизировать этот процесс?

Описанный процесс мы производим вручную, автоматизация здесь касается лишь эффективного сужения диапазона для поиска. Но мы можем запускать git bisect со скриптом (если у нас есть скрипт, умеющий определять, хороший у нас коммит или плохой. Это позволяет автоматизировать весь процесс компиляции, тестирования и пометки коммитов как «хороших» или «плохих».

Примечание. Такой скрипт должен иметь код выхода 0, если текущий исходный код хороший/старый (good/old). Если исходный код плохой/новый (bad/new), код выхода должен быть в диапазоне чисел от 1 до 127 (включительно), кроме 125.

Заключение

Для облегчения жизни разработчика создано множество различных инструментов. Я уверен, что умение отлаживать код — особый навык, который должен быть в арсенале каждого разработчика. Надеюсь, моя статья поможет вам научиться работать с таким прекрасным инструментом отладки как git bisect. А если захотите узнать о нем больше, нужные сведения можно найти в документации.

Источник

Отладка с Git

В этой статье мы рассмотрим два метода Git для отладки ошибок в базе кода — blame и bisect. С помощью Git blame описываются детали изменения каждой строки в файле, а bisect выполняет бинарный поиск по коммитам. Blame и bisect помогают устранять ошибки в больших базах кода с помощью обнаружения корневого коммита, приводящего к возникновению проблемы.

Подготовка файлов для отладки

Чтобы продемонстрировать функции отладки Git, мы будем использовать репозиторий на GitHub для запуска команд и воспроизведения результатов. Чтобы клонировать репозиторий, выполните следующую команду:

После завершения процесса клонирования измените активную директорию на клонированную папку.

Теперь рассмотрим файлы в репозитории.

Команда git log выводит историю проекта.

В этом руководстве мы рассмотрим оба метода Git для отладки ошибок в коде. Начнем с Git blame.

Отладка через историю файлов

Вывод команды blame выглядит следующим образом:

Команды git show выводит список изменений в коммите.

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

Отладка через бинарный поиск

Команда Git blame используется тогда, когда известен файл, в который было внесено изменение. Представьте сценарий, в котором виден результат ошибки, однако не известно, какая часть кода приводит к ней! В таких случаях на помощь приходит Git bisect.

Для начала в истории нужно определить коммит, в котором отсутствовала ошибка, то есть, «хороший» коммит. Цель процесса bisect состоит в том, чтобы найти коммит между этим «хорошим» коммитом и текущим «плохим» коммитом, который привел к возникновению ошибки. При инициировании процесса Git bisect запускается мастер, а репозиторий переходит во временный режим. На каждом этапе мастер изменяет состояние репозитория на промежуточный коммит и спрашивает, присутствует ли ошибка. Процесс продолжается до выявления первого «плохого» коммита.

Начнем с мастера bisect.

Читайте также:  Что значит система ноу фрост в холодильнике

Затем нужно указать хорошие и плохие коммиты для запуска мастера. Выбираем первый коммит #8dd76fc в истории репозитория в качестве хорошего коммита.

Поскольку последний коммит содержит ошибку, пометим его как плохой коммит.

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

Обратите внимание, что у нас есть девять коммитов, следовательно, потребуется примерно три шага (так как 2, возведенное в степень 3, равно 8, что очень близко к 9). При наличии тысячи коммитов потребовалось бы около десяти шагов (так как это процесс бинарного поиска).

Коммит, вызвавший ошибку, успешно определен.

Чтобы выйти из мастера bisect, выполните команду reset.

Автоматизация процесса Git Bisect

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

Заключение

В этом руководстве мы рассмотрели простой пример для объяснения двух динамических и полезных инструментов Git. Таким образом, если вы знаете исходный файл ошибки, то используйте команду Git blame, а если известно лишь поведение ошибки, то вам нужен процесс bisect.

Источник

git bisect: путешествие по времени и багам

Добрый день, меня зовут Павел Поляков, я Principal Engineer в каршеринг компании SHARE NOW, в Гамбурге в 🇩🇪 Германии. А еще я автор Telegram-канала Хороший разработчик знает, где рассказываю обо всем, что должен знать хороший разработчик.

Git bisect: путешествие по времени и багам

Не важно насколько хорошо ваш проект покрыт тестами, вы не можете протестировать все.

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

Готовы путешествовать во времени по своему коду?

Не эффективный метод дебага — проверять коммит за коммитом

Один раз ситуация, которую я описал выше, произошла со мной.

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

Это может сработать, если у вас пара коммитов. Но чем больше коммитов вам нужно проверить, те больше времени это займет, причем это экспоненциальный рост.

С другой стороны, git bisect использует бинарный поиск для поиска среди ваших коммитов. И это быстрее!

Хорошо, а что такое бинарный поиск?

Бинарный поиск работает с отсортированной информацией. Вместо проверки элементов один за другим, от первого к последнему, алгоритм начинает сразу с элемента в середине.

В зависимости от условий вашего поиска, алгоритм сделает что-то из списка:

вернет текущий элемент

проверит все элементы слева о текущего

проверит все элементы справа от текущего

На каждой итерации алгоритм проверяет средний элемент в списке, который постоянно уменьшается.

TL;DR: бинарный поиск не проверяет каждый элемент в списке, он проверяет только часть. И все равно находит результат.

git bisect работает аналогично.

Эффективный метод дебага: git bisect

Сейчас ваше приложение не работает как положено. Но мы знаем, что два месяца назад эта фича работала. Какой-то коммит, который мы добавили в течении этого времени внес регрессию.

В чем проблема? Мы не знаем когда это произошло.

Есть один коммит, который разделяет хронологию вашего приложения на до и после:

все что было ДО этого плохого коммита — ваше приложение работало отлично

все что было ПОСЛЕ этого плохого коммита — ваше приложение поломано

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

Он использует самый свежий «плохой» коммит и последний известный «хороший» коммит как диапазон, который нужно проверить.

git bisect выбирает коммит в середине этого списка и просит вас указать — это «хороший» или «плохой» коммит. Присутствует ли регрессия в этом коммите? Он продолжает сужать список, пока не найдет тот самый коммит, который привел к регрессии.

Теперь разберем подробно:

git bisect start запускает режим bisect

git bisect good — говорит bisect о последнем «хорошем» коммите, когда приложение работало правильно

Bisecting: 4 revisions left. — примерное количество шагов, которые понадобятся

Вместо того чтобы проверять коммиты один за другим, git bisect сразу прыгает в середину вашего списка (здесь, коммит 02ca345f3e29217bb6553 ) и вы можете проверить, как ваш код работал во время этого коммита. Круто!

Теперь вы можете запустить ваше приложение, запустить тесты. Может быть вручную проверить работает ли фича на локальном окружении. Я повторяю, проверьте вручную есть ли сейчас баг. Это важно!

Почему я настаиваю? Потому что, когда я использовал bisect впервые, у меня в голове был кандидат на «плохой» коммит. Вместо того, чтобы проверить мое приложение вручную на каждом этапе, я просто говорил bisect свое мнение, о том есть ли сейчас регрессия. В итоге git bisect примел меня к тому самому коммиту, который я и подозревал.

Читайте также:  f3 cool что это такое в инстаграме

Однако, когда я начал использовать git bisect правильно, я понял, что ошибался. Тот коммит был невиновен. Я быстро нашел настоящего виновника.

Если приложение работает, git bisect good скажет git bisect исследовать «правую» часть, коммиты в будущем.

Отступление: если вам необходимо вручную проверять приложение, то, скорее всего, лучше написать тест. В случае моего бага, я написал интеграционный тест с моками ответов от двух сервисов.

Все это намного быстрее чем проверять каждый коммит и искать иголку в стоге сена!

Хотите узнать больше? Посмотрите официальную документацию по git bisect.

Использовали git bisect раньше? Пишите в комментариях, мне интересно.

А еще.

Здесь говорю опять я, Павел. В конце еще раз приглашу вас в свой Telegram-канал. На канале Хороший разработчик знает я минимум три раза в неделю простым языком рассказываю про свой опыт, хард скиллы и софт скиллы. Я 15+ лет в IT, мне есть чем поделиться. Все это нужно разработчику, чтобы делать свою работу хорошо, быть востребованным на рынке и получать высокую компенсацию.

Источник

Обнаружение ошибок с помощью Git

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

Аннотация файла

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

Обратите внимание, что первое поле — это неполная SHA-1 сумма последнего коммита, который изменял соответствующую строку. Следующими двумя полями являются значения, извлечённые из этого коммита — имя автора и время создания коммита — таким образом, вы можете легко увидеть кто изменял строку и когда. После этого следуют номер строки и содержимое файла. Обратите внимание на строки со значением ^4832fe2 в поле коммита, так обозначаются те строки, которые были в первом коммите этого файла. Этот коммит был сделан, когда данный файл был впервые добавлен в проект и с тех пор эти строки не были изменены. Немного сбивает с толку то, что вы уже видели в Git, по крайней мере, три различных варианта использования символа ^ для изменения SHA-1 коммита, в данном случае этот символ имеет такое значение.

Это, действительно, полезно. Обычно вы получаете в качестве изначального коммит, в котором вы скопировали код, так как это первый коммит, в котором вы обращаетесь к этим строкам в этом файле. Но в данном случае Git сообщает вам первый коммит, в котором эти строки были написаны, даже если это было сделано в другом файле.

Бинарный поиск

Git выяснил, что произошло около 12 коммитов между коммитом, который вы отметили как последний хороший коммит (v1.0), и текущим плохим коммитом, и выгрузил вам один из середины. В этот момент вы можете запустить ваши тесты, чтобы проверить присутствует ли проблема в этом коммите. Если это так, значит она была внесена до выгруженного промежуточного коммита, если нет, значит проблема была внесена после этого коммита. Пусть в данном коммите проблема не проявляется, вы сообщаете об этом Git с помощью git bisect good и продолжаете ваше путешествие:

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

Этот коммит хороший и теперь Git имеет всю необходимую информацию для определения того, где была внесена ошибка. Он сообщает вам SHA-1 первого плохого коммита и отображает некоторую информацию о коммите и файлах, которые были изменены в этом коммите, так, чтобы вы смогли разобраться что же случилось, что могло привнести эту ошибку:

Когда вы закончили бинарный поиск, нужно выполнить git bisect reset для того, чтобы вернуть HEAD туда, где он был до начала поиска, иначе вы останетесь в, довольно, причудливом состоянии:

Источник

Сказочный портал