solovyov.net

Rebase для бедных в Mercurial

· · hg, programming, mq

Пока честный rebase для меркуриала находится в стадии проекта для GSoC, я расскажу про то, как его сделать с помощью существующих инструментов - всё же это бывает полезно.

Итак, что у нас есть? У нас есть какой-то проект, разрабатывающийся где-то там (вне пределов текущего репозитория ;), и локальные изменения (ещё нигде не опубликованные - это важный момент1), которые ответвляются не от последней ревизии, а где-то чуть раньше. Выглядит это всё так:

o  [4:90fba61256bd] by Outer Developer
|  third commit
|
o  [3:1bd353a07bad] by Outer Developer
|  second commit
|
| @  [2:1685d3c280ff] by Alexander Solovyov
| |  my second
| |
| o  [1:337f09cca099] by Alexander Solovyov
|/   my first
|
o  [0:7573fff4d9c9] by Outer Developer
   initial commit

Что хочется увидеть? Хочется увидеть, как изменения из моего репозитория будут ответвляться от 90fb, а не от 7573.

Что делать?

Первым делом понадобится включить плагин mq. Он изначально предназначен совсем не для того, что я сейчас собираюсь делать, поэтому действия выходят слегка многословными, но ведь интересует-то результат?

Весь сценарий - вытащить изменения из рабочей копии в очередь патчей, применить патчи к последней ревизии и экспортировать их как чейнджсеты.

$ hg qimport -r 1:2      # импортируем в очередь необходимые чейнджсеты (превращая их в патчи mq)
$ hg qpop -a             # отменяем импортированные патчи от рабочей копии
$ hg up -C tip           # обновляемся до последней ревизии с потерей изменений
$ hg qpush -a            # применяем патчи к рабочей копии
$ hg qfinish qbase:qtip  # экспортируем все патчи в обычные чейнджсеты

qtip и qbase - это такие специальные виртуальные теги (в обычном состоянии есть только один подобный - tip), которые вводит mq. qbase - это первый из применённых патчей, qtip - соответственно, последний. Из интересных тегов ещё есть qparent - это чейнджсет, родительский для qbase.

Вот это и всё - теперь история репозитория выглядит вот так:

@  [4:55550600d079] by Alexander Solovyov
|  my second
|
o  [3:2a783dd32af9] by Alexander Solovyov
|  my first
|
o  [2:90fba61256bd] by Outer Developer
|  third commit
|
o  [1:1bd353a07bad] by Outer Developer
|  second commit
|
o  [0:7573fff4d9c9] by Outer Developer
   initial commit

Как быть?

Ещё раз замечу - использовать такое можно только пока изменения не опубликованы - mq изменяет историю (точно так же, как это делает rebase). Но в отдельных случаях бывает такое бывает полезно или просто нужно. ;)

P.S. В статье я не касаюсь механизма и принципов работы mq - может, напишу об этом в будущем. А пока есть два пути - почитать hgbook и поэкспериментировать самому (начав с hg help mq), хотя бы на примере этого рецепта, посмотрев, что делают команды с логом и рабочей копией.