Pull to refresh

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

Reading time2 min
Views35K
Однажды старший программист Антон, попивая кофе и вспоминая уволенного в предыдущей статье Васю, просматривал очередной тикет в багтрекере. В тикете было сказано, что одна из программ в очень важном проекте стала при некоторых условиях возвращать «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.
Tags:
Hubs:
Total votes 67: ↑62 and ↓5+57
Comments90

Articles