вторник, 27 декабря 2011 г.

Automate git bisect with simple shell script

Короткая заметка об автоматизизации использования git-bisect с помощью shell-скрипта для поиска коммита в котором сломалась сборка.
 
В какой-то момент я обнаружил, что интеграционные тесты в моём личном проекте стали завершаться с ошибкой. Лезть в тесты и исправлять их, честно признаюсь, было лень. Зная тот факт, что раньше они не падали, я решил пойти другим путём — найти коммит который их сломал и уже тогда решать как лучше устранить проблему.

В замечательной системе контроя версий git есть для такой задачи отдельный инструмент, который зовётся git bisect. При запуске вы указываете ему две границы, между которыми будет вестить поиск — коммит в котором всё работало и коммит в котором не работает. Он создаёт временный бранч на основании коммита «по середине», вы проверяете работает или нет, сообщаете git-у, он снова создаёт временный бранч на основании текущего коммита и одной из границ (в зависимости от того рабочий текущий коммит или нет). И так далее, пока «плохой» коммит не будет найден. Если вы из этого ничего не поняли, значит я невнятно объясняю, т.к. всё довольно просто. Возможно, станет яснее, если я скажу, что используется алгоритм бинарного поиска.

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

Давайте просто сделаем это!

$ git bisect start HEAD 475f0b0e1a78e7790fa99ec94fb07e293609a51d
$ git bisect run ./it.sh
[skip]
aec3ef18c24d98fe3caa9223ee289bf67c696f3d is the first bad commit
commit aec3ef18c24d98fe3caa9223ee289bf67c696f3d
Author: Slava Semushin 
Date:   Wed Nov 16 22:13:35 2011 +0700

    Fixed site displaying for locales which has no translation.
    
    Use English messages instead.

:040000 040000 dd845be0bf17c05f48a9743ca1093b9c9e84b230 ec69db2bb808bdb7073b14827736f5bbf7a8740f M src
bisect run success

Вуаля!

Сначала мы инициализировали git bisect и указали ему, что в текущем (HEAD) состоянии репозитория у нас ничего не работает. А ведь в коммите 475f0b0e1a78e7790fa99ec94fb07e293609a51d всё работало :)

Следующей командой мы запустили наш поиск и в качестве скрипта, который решает работает или нет, передали it.sh из текущего каталога.

Каким этот скрипт должен быть? Он должен завершаться с кодом возврата 0, если текущий коммит рабочий, либо с каким-либо другим из диапазона от 1 до 127, для указания, что коммит сломан. (Код возврата 125 сигнализирует что текущий коммит нужно пропустить.

В моём случае скрипт был такой:

$ cat it.sh
#!/bin/sh
mvn -P test clean verify -Dit.test=WhenUserRegisterAccount
exit $?

Здесь с помощью Maven запускаются интеграционные тесты (причем, чтобы проверялось быстрее, я запускаю только некоторые из них). Если тесты падают, то Maven возвращает ненулевой код возврата, который возвращает и скрипт.

Тут и сказочке конец, а кто не понял F1 man git-bisect.

Комментариев нет:

Отправить комментарий