Git. Как найти коммит который все сломал?
Возникали ли у вас паника, когда после git pull
-а все напрочь ломается и ничего не работает или работает, но не все? В этом случае можно искать "коммит-киллер" разными способами. Например, постепенно откатывая HEAD, но я расскажу более прогрессивный метод.
Итак, речь пойдет о команде git bisect
. Она не раз спасала меня от провала и экономила приличное количество времени при поиске ошибки. Работает она достаточно просто. Думаю, многие слышали про метод половинного деления (или дихотомии) и именно по такому принципу она и работает.
Мы указываем коммит при котором воспроизводится ошибка (обычно это текущее состояние) и коммит при котором все работает. Далее происходит checkout
к коммиту между этими состояниями. Наша задача проверить работоспособность и известить git bisect
о результате (все хорошо или все по-прежнему плохо). И так до тех пор пока не закончится поиск. В конце концов мы получаем коммит, после которого обнаружилась ошибка. Остается только посмотреть все изменения и исправить код в нужных местах.
Теперь к практике. Допустим мы работали с проектом, который помечен тегом 1.3.7 (тут все работает) и спулили последние изменения с сервера (обнаружилась ошибка). Наша последовательность действий такова:
git bisect start
- начинаем поискgit bisect bad
- помечаем текущий HEAD, как "испорченный"git bisect good 1.3.7
- указываем рабочий коммит- проверяем работоспособность
- вызываем
git bisect good
, если все работает илиgit bisect bad
, если ошибка еще присутствует - повторяем шаги 4 и 5 пока не дойдем до состояния, которое порождает ошибку
- смотрим список изменений и ищем причину ошибки
- возвращаем
HEAD
в первоначальное состояние с помощьюgit bisect reset
- исправляем ошибку
В git bisect good
и git bisect bad
можно передать тег или хэш коммита, если этого не сделать, то туда подставится текущее состояние.
Если коммитов очень много и можно написать скрипт проверки, то можно использовать команду git bisect run test-script.sh
. Данный скрипт должен возвращать 0
, если проверка прошла и "что угодно" в противном случае.