Fork me on GitHub
12/10/2009

hgsubversion

Иван Сагалаев начал тему взаимодействия DVCS с Subversion, я продолжу и расскажу про свой опыт с Mercurial+Subversion.

У нас, как и у многих других, используется Subversion. Однако меня после тесного общения с Mercurial и Git как-то очень быстро стали утомлять:

  • svn stat/diff показывает изменения только в текущей директории
  • svn up долго-долго шуршит винчестером прежде чем что-то сделать
  • нет сети - нет работы. Дело даже не в коммите, а хотя бы посмотреть лог

и еще тысяча маленьких полезных вещей, которые с ходу не вспомнишь, но отсутствие которых допекает (цветные diff'ы, быстрый revert всех правок, удаление "левых" файлов, удобные add, возможность скопировать/перенести файл с правками и прочее и прочая).

Я было соблазнился на git-svn, но Александр Соловьев, адепт Mercurial посоветовал hgsubversion. Правда автор этого расширения предупреждает: "right now it is not ready for production use" и это похоже на правду.

Инсталляция не доставляет хлопот: практически все необходимые зависимости есть в Ubuntu 9.04 (разве что сам Mercurial нужно обновить до 1.3).

После этого появляется возможность работать с репозиториями svn+http:// почти как с настоящими hg-репо. Т.е. никаких дополнительных/специфичных команд не требуется, а все обычные команды работают как должны -- hg pull "вытаскивает" изменения с удаленного репозитория, hg commit коммитит в локальный репо, hg push -- отсылает изменения с локального на удаленный репозиторий, hg in показывает какие новые изменения придут с pull-ом, а hg out -- какие уйдут с push-ем.

Всё хорошо ровно до того момента, как вы пожелаете сделать мердж. hg push невнятно ругнётся и вы вспомните, что еще не добавили плагин rebase для Mercurial ;) Собственно именно в этом и заключается особенность работы с svn-репо. Перед push-ем, вам нужно "линеаризовать" историю, "перенести" свою ветку изменений поверх последнего коммита так, чтобы история была линейной. После этого можно будет успешно отослать изменения в svn-репозиторий.

Собственно именно к rebase у меня больше всего нареканий.

Во-первых, hg не делает rebase автоматически. В большинстве случаев при работе с svn понятно какие коммиты куда переносить (коммиты, которых еще нет в svn-репо перенести поверх тех, которые уже там есть), но приходится делать "рукаи": hg glog глазами смотришь, запоминаешь/записываешь на бумажке с какой на какую ревизию переносить, hg rebase -s X -d Y.

Во-вторых, rebase переносит коммиты "как есть". Т.е. нельзя сказать "перенеси не коммиты, но изменения с этой ветки". Т.е. было у вас 20 коммитов в ветке, они перенесутся как 20 коммитов. И тут есть два нюанса:

  • до обновления ваши коммиты были "правильными", после rebase несмотря на отсутствие конфликтов, они могли поломать что-то в обновлениях, пришедших из svn. Т.е. вы обновились, реализовали фичу/закрыли тикет, написали/исправили тесты, всё ок, закоммитили. Потом вы снова обновляетесь с svn и надо бы "перенести" свои коммиты поверх изменений, проверить тесты, и потом закоммитить, но hg в отсутствие конфликтов перенесет коммиты as is, поэтому есть вероятность писать еще фикс "в догонку".
  • иногда всё же хочется, чтобы был один коммит: "сделано то-то", а не четыре: "сделана база для того-то", "написаны основные тесты", "реализована вся функциональность", "дополнительные тесты и фиксы". rebase такого не делает.

Знатоки hg скажут, что это я валю с больной головы на здоровую, и что rebase не для этого, и что нужно использовать patch queue, но я попробовал и мне с ними не особо комфортно.

Далее, еще один "баг", с которым я столкнулся: бранчи из hg-репо не переносятся в svn. Т.е. в hg нельзя создать новый svn-бранч. Это очень плохо.

Но это еще не всё. Mercurial не особо помогает и в мерджах между бранчами. Т.е. если у нас есть в svn trunk (который переносится в hg как default) и бранч M3 (который переносится в hg как бранч M3), то hg нам не поможет их смерджить. Обычный hg merge не работает, потому что для svn нужна линейная история, а hg rebase не подходит, потому что нам по факту нужно скопировать изменения одним патчем, а не перенести коммиты.

Если подвести итоги, то hgsubversion достаточно хорош как svn-клиент, но полноценно комфортно взаимодействовать hg с svn он не позволяет.

Комментарии

Все статьи