Чем опасен rebase-2, или как rebase мешал баг искать

от автора

Однажды старший программист Антон, попивая кофе и вспоминая уволенного в предыдущей статье Васю, просматривал очередной тикет в багтрекере. В тикете было сказано, что одна из программ в очень важном проекте стала при некоторых условиях возвращать «BAD» вместо «GOOD». Недолго думая, Антон написал тестовый скрипт и приступил к поиску причины такого поведения.

testscript.sh

#!/bin/bash result=`./project.sh` echo $result if [[ "$result" == "GOOD" ]] then     echo "Test passed"     exit 0 elif [[ "$result" == "BAD" ]] then     echo "Test failed"     exit 1 else     echo "Can not apply test"     exit 125 fi 

git bisect start ./testscript.sh git bisect bad ./testscript.sh git bisect good … 

В компании использовали rebase, история коммитов была линейной, и поиск по ней доставлял Антону одно удовольствие.
Как вдруг:
— Хм… Проект не компилируется, тест прогнать не получится. Ну ладно, не беда, пропустим: git bisect skip.
— Что за ерунда? Опять не компилируется. Опять пропустим…
— Опять??? Какой @#$%^ запушил столько битых коммитов?

Через некоторое время перед Антоном открылась безрадостная картина: 30 коммитов, на которых проект не собирается, и где-то среди них коммит с ошибкой.

Антон набрал номер Васи.

Антон: — Привет, Василий! Подскажи, откуда в репозитории 30 ревизий, на которых проект не собирается?
Вася: — А… Помню-помню. Я разрабатывал важную фичу в своей ветке, получилось 30 коммитов, каждый — одно цельное изменение, перед коммитами прогонял все тесты, всё как по учебнику. Но в это время Петя в мастере сильно изменил API, который использовался в моих коммитах. Поэтому когда я локально сделал rebase, мои коммиты оказались после Петиного, и проект на них собираться перестал.
Антон: — И что, ты не проверил это, перед тем, как пушить?
Вася: — Конечно, проверил. И создал коммит с переходом моей фичи на новое API, после чего проект снова стал собираться.
Антон: — И как же мне теперь локализовывать ошибку в этих 30 коммитах?
Вася: — Извини, Антон. Я уволен, и теперь это не моя проблема.

В это время в параллельной реальности..

Антон приступил к поиску причины бага в очень важном проекте. В компании используют merge, история коммитов нелинейна, ручной поиск по истории не доставляет Антону радости, поэтому он делегирует это дело git-bisect, используя заранее подготовленный скрипт.

git bisect run ./testscript.sh 

Git bisect весело побежал по коммитам, автоматически запуская тестовый скрипт и расставляя метки good/bad, пропустил единственный нерабочий коммит и выдал результат.

f35d44060c4f2ae251046c0c20ae1e1f68044812 is the first bad commit 

Антон: — Эй, Василий! У тебя в коммите f35d440 ошибка.
Вася: — Хорошо, посмотрю.

Через 5 минут:
Вася: — Готово, исправил.
Антон: ОК.

Мораль: любой rebase (в том числе локальный) меняет контекст, в котором были написаны коммиты, и в истории могут остаться «битые» ревизии. Помните об этом.

Пример проекта на github.

ссылка на оригинал статьи http://habrahabr.ru/post/179673/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *