суббота, 14 января 2012 г.

Mercurial Queues

В этой статье пойдёт речь про одно из дополнений к Mercurial~--- Queues (далее просто MQ). Это дополнение распространяется вместе с Mercurial, поэтому для начала использования достаточно включить его, добавив следующие строки в .hg/hgrc:

[extensions]
hgext.mq =

Предназначение

Собственные патчи к Open Source программам

Начнём с того, зачем оно вообще нужно. Самый простой пример~--- вы устанавливаете программу из исходных кодов и обнаруживаете в ней баг. Разумеется, перед началом использования программы, вы исправляете его и через некоторое время забываете о сделанных изменениях. Спустя некоторое время, вы решаете обновить программу. Если новая версия также содержит тот самый баг, то придётся выдирать изменения из старой версии и применять их к новому исходному коду. Это утомительно и в процессе легко совершить ошибки. Тут бы помогло сохранение патча при первоначальном исправлении бага, но:

  1. Делать это лениво.
  2. Патч мог потеряться с течением времени.
  3. Исходный код в новой версии программы мог измениться настолько, что старый патч уже не подходит. Надо бы сделать новый патч, но см. п. 1.

Понятное дело, ситуация ухудшается вместе с ростом числа патчей.

Участие в Open Source проектах

Похожие проблемы возникают при участии в Open Source проектах. Вы пишите патч, отправляете команде разработчиков, а они тормозят с его принятием. Пока они думают, хотелось бы иметь эти изменения хотя бы в своей локальной установке, при этом параллельно обновляя программу и подгоняя патч под её новые версии.

Управление патчами

Приведённые примеры являются простыми проявлениями проблемы "управления патчами". У вас есть "образцовый" исходный код, который вы не можете менять. В то же время, вы хотите внести некоторые изменения поверх образцового кода, при этом сохранив эти изменения отдельно, чтобы использовать их повторно для новых версий.

Первыми почувствовали неудобство разработчики ядра Linux, когда в конце 90-х они начали поддерживать целые наборы (сотни и тысячи) патчей для разных целей. В начале 2003-го года Andreas Gruenbacher и Martin Quinson выпустили утилиту Quilt, которая управляла стеком патчей над директорией с исходным кодом. MQ является реализацией Quilt-подобных команд для Mercurial.

Дополнительную агитацию за использование MQ можно прочитать в главе 12 "Managing change with Mercurial Queues" hgbook, ну а мы перейдём к практике.

Пример

Наложение патча на новую версию без конфликта

Самый простой случай. Пусть уже существует какой-то репозиторий. Мы клонируем его себе на компьютер и делаем изменения. Затем репозиторий обновляется и мы накладываем тот же самый патч уже на новую версию.

Создание репозитория и подключение MQ

Для простоты вместо клонирования какого-нибудь существующего репозитория, создадим себе новый:

user@laptop:~$ hg init testmq
user@laptop:~$ cd testmq/
user@laptop:~/testmq$ echo Hello, World1 > text
user@laptop:~/testmq$ hg ci -A -m 'initial commit'
adding text

Для начала работы с MQ сначала включаем это расширение:

user@laptop:~/testmq$ echo -e "[extensions]\nhgext.mq =" >> .hg/hgrc

А затем создаём новый репозиторий патчей:

user@laptop:~/testmq$ hg init --mq

Кстати, в уже упоминавшейся hgbook используйте команда hg qinit для этих же целей, но на сегодня она объявлена устаревшей, в чём можно убедиться, набрав hg help qinit.

Создание патча

Настало время создать наш патч для замены 1 на восклицательный знак. Делается это до безобразия просто:

user@laptop:~/testmq$ sed -i "s/1/\!/" text
user@laptop:~/testmq$ hg qnew first.patch

И это всё!

Повторное применение патча

Теперь разберёмся с повторным применением патча. Перед затягиванием новых коммитов в свой локальный репозиторий необходимо отменить все патчи, иначе hg будет ругаться:

user@laptop:~/testmq$ hg ci
abort: cannot commit over an applied mq patch

Отменяем патч:

user@laptop:~/testmq$ hg qpop
popping first.patch
patch queue now empty

Симулируем затягивание (hg pull) простым созданием нового коммита:

user@laptop:~/testmq$ echo "Hello, World 2\!" >> text
user@laptop:~/testmq$ hg ci -m 'something new

И заново накладываем патч:

user@laptop:~/testmq$ hg qpush first.patch
applying first.patch
now at: first.patch

В данном случае патч не конфликтует с затянутыми коммитами, поэтому наложение прошло без проблем:

user@laptop:~/testmq$ cat text
Hello, World!
Hello, World 2\!

Наложение патча на новую версию с конфликтом

Обновление патча

Как вы могли заметить, в подопытном файле text сейчас стоит совершенно ненужный слеш перед восклицательным знаком. Исправим это.

user@laptop:~/testmq$ sed -i "s/\\\\//" text
user@laptop:~/testmq$ hg qrefresh

Последней командой мы обновили наш патч, чтобы он включал в себя удаление слеша.

Затягивание конфликтного коммита

Как и в прошлый раз, симулируем затягивание новых коммитов:

user@laptop:~/testmq$ hg qpop
popping first.patch
patch queue now empty
user@laptop:~/testmq$ sed -i "s/Hello, World 2\\\\\!/Completely different line\!/" text
user@laptop:~/testmq$ hg ci -m 'new commit'

Теперь пробуем повторно применить наш патч и видим ошибку:

user@laptop:~/testmq$ hg qpush first.patch 
applying first.patch
patching file text
Hunk #1 FAILED at 0
1 out of 1 hunks FAILED -- saving rejects to file text.rej
patch failed, unable to continue (try -v)
patch failed, rejects left in working dir
errors during apply, please fix and refresh first.patch

Исправление патча

Наша задача исправить патч. Так как наш патч состоит из одного куска, в котором изменяются 2 строки, то придётся переделать его весь. В реальности же патч почти всегда содержит в себе несколько правок далеко отстоящих друг от друга строк и в случае конфликта придётся править только проблемные куски. Итак, исправляем патч:

user@laptop:~/testmq$ rm text.rej
user@laptop:~/testmq$ echo Hello, World\! > text
user@laptop:~/testmq$ echo Hello, World 2\! >> text
user@laptop:~/testmq$ echo Completely different line\! >> text
user@laptop:~/testmq$ hg qrefresh

Для дальнейшего изучения

Лучшим источником информации по MQ безусловно является hgbook. Там этой теме отведено 2 полноценные главы, плюс в конце книги располагается справочник по командам. Материал подан очень профессионально и в большом объёме. Данная статья является лишь введением и призвана заинтересовать в дальнейшем изучении MQ.

1 комментарий:

  1. Примеры уставных документов по декларированию https://www.oprf.ru/personal/22924
    Шаблоны действующих документов по декларированию https://oprf.ru/personal/22179
    Образцы уставных документов по сертификации https://oprf.ru/personal/22183
    Шаблоны действующих документов по сертификации http://www.asfera.info/news/one-29640.html

    ОтветитьУдалить