четверг, 6 февраля 2014 г.

Магический git rebase -i

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

Это часть. когда то была оформлена отдельной веткой, но уже давно влита в master отдельными коммитами (без --squash) , и "вросла" в продукт.

Также было несколько коммитов с error-fix-ами для этой функциональности уже после merge.

Переписывание сильное, старый код не нужен совсем. И логика и функциональность будет новой.

Появилась задача "выпилить это" совсем.

На помощь приходит rebase.

Пометил для удобства тегами from-to влитую ветку.
Очень повезло что там все очень линейно.
Создал из тега from - новый branch

git checkout from
git checkout -b new 
 И запустил интерактивный rebase из master
git co master
git rebase -i --onto new --root HEAD
 Удаляю там в редакторе коммиты c from..to , что б они в новую ветку не попали.

И rebase выполняется, перекладывая оставшиеся коммиты из master в new за вычетом удаленных.
Изредка конфликты возникают (это error-fix на удаленный функционал) приходится их решать руками, и продолжать через
git rebase --continue

Процедура довольно простая, но это же git, уверен что был путь и попроще. Советуйте.

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

Ну, например:
Был коммит, исправляющий ошибку, небольшой в две строки.
Вместе с ним, видимо от недовольства как выровнен остальной код в файле, был сделан retab и reindent.
Файл стал красивее, но git считает что переписано куча всего.
Получайте конфликты при rebase.