Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
hgbook.pdf
Скачиваний:
52
Добавлен:
17.03.2015
Размер:
3.15 Mб
Скачать

Управление изменениями с Mercurial Queues

$ hg qrefresh -m 'Good change' $ hg qfinish tip

$ hg qapplied

$ hg tip --style=compact

0[tip] ea28b7ac83fb 2012-02-02 14:09 +0000 bos Good change

Команда hg qfinish принимает опцию --all или -a, который преобразует все применённые патчи в обычные ревизии.

Кроме того, можно превратить существующую ревизию в патч, с помощью опции -r команды hg qimport.

$ hg qimport -r tip $ hg qapplied

0.diff

Обратите внимание, что это имеет смысл только для преобразования набора изменений в патч, если вы не распространяете ревизии в любой другой репозитарий. ID импортируемого набора изменений будет изменяться каждый раз, когда вы обновляете патч, который делает Mercurial рассматривать его как не связанный с первоначальной ревизией, если вы его передадите в любой другой репозитарий.

12.8. Получение максимальной производительности от MQ

MQ очень эффективен при обработке большого количества исправлений. Я провел несколько экспериментов производительности в середине 2006 года для доклада, который я делал в 2006 на конференции EuroPython (на современном оборудовании, вы должны ожидать более высокую производительность, чем вы увидите ниже). Я использовал в качестве моего набора данных серии патчей linux 2.6.17-mm1, которая состоит из 1738 патчей. Я применил их на поверх репозитория linux ядра, содержащее всего 27472 ревизии между linux 2.6.12-rc2 и linux

2.6.17.

На моём старом, медленном ноутбуке, я выполнил hg qpush -a для всех 1738 патчей в 3,5 минуты, а hg qpop -a всего в 30 секунд. (На новом ноутбуке, время добавления всех патчей снизилось до 2 минут). Я выполнил qrefresh для одного большого патча (который состоял из 22779 строк изменений в 287 файлах) за 6,6 секунды.

Очевидно, что MQ хорошо приспособлен к эксплуатации на больших деревьях, но есть несколько трюков которые можно использовать для получения наилучшей производительности.

Прежде всего, попытайтесь выполнять «пакетные» операции вместе. Каждый раз, когда вы запускаете qpush или qpop, эти команды проверяют рабочую директорию один раз, чтобы убедиться, что вы не внесли каких нибудь изменений, а затем забыл запустить qrefresh. На небольшом дереве, время этой проверки невелико. Однако, на средних деревьях (содержащих десятки тысяч файлов), это может занять секунду или даже больше.

Команды qpush и qpop позволяют вставлять и извлекать несколько патчей сразу. Вы можете указать «патч назначения» который вы хотите применить последним. qpush с указанным назначением, то он будет вставлять патчи до этого патча в верх стека применения. qpop с назначением, MQ извлекает патчи до того как патч назначения не окажется на самом верху.

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

12.9. Обновление патчей когда исходный код измененился

Как правило имея патч на верху стека вы не изменяете напрямую нижележащий код в репозитории. Если вы работаете над изменениями в коде третьих сторон, или над особенностью, которая занимает больше времени, чем скорость развития изменений кода внизу, вам часто нужно синхронизироваться с исходным кодом, и исправлять блоки в своих патчах, которые уже не применяются. Это называется перебазирование серии патчей.

149

Управление изменениями с Mercurial Queues

Проще всего это сделать так: выполнить hg qpop hg -a для ваших патчей, затем hg pull ревизий из основного репозитория, и, наконец выполнить hg qpush -a ваших патчей снова. MQ будет останавливать вставку каждый раз, когда проходит через патч, который не применяется из-за конфликтов, что позволяет исправлять ваши конфликты, и выполнять qrefresh для пострадавших патчей, и продолжать вставку, пока не исправите весь стек.

Этот подход прост в использовании и работает хорошо, если вы не ожидаете изменений в исходный код, которые повлияют на эффективность ваших патчей. Если ваш стек патчей касается кода, который модифицируются часто или агрессивно в базовом репозитории, однако, исправление отклонённых блоков вручную быстро становится скучным.

Можно частично автоматизировать процесс перебазирования. Если ваши патчи применяются чисто к другим ревизиям из репозитория, MQ может использовать эту информацию, чтобы помочь вам в разрешении конфликтов между патчами и различными ревизиями.

Этот процесс немного сложнее.

1.Во-первых, выполняем hg qpush -a применяя все ваши патча к старшей ревизии, к которой вы знаете, что они применяются чисто.

2.Сохранить резервную копию исправляемого каталога с помощью команды hg qsave hg -e hg -c. Она выводит имя директории, в которой она сохранит патчи. Это сохранит исправления в каталоге называемом .hg/ patches.N, где N является малым числом. Она также «сохраняет ревизию» поверх которой применяются патчи, и записывает состояние файлов series и status.

3.Используйте hg pull для внесения изменений в основной репозиторий. (Не запускать hg pull -u, смотрите ниже, почему.)

4.Обновитесь до новой верхней ревизии, используя hg update -C, переписываяизменения ваших патчей.

5.Объедините все патчи hg qpush -m -a. Опция -m qpush говорит MQ выполнить трехстороннее слияние, если патч не может применится.

В hg qpush hg -m, каждый патч в файле series применяется в обычном режиме. Если исправление применяется с неточностями или отвергается, MQ смотрит на вашу очередь qsaved, и также выполняет трехстороннее слияние с соответствующей ревизией. Для слияния Mercurial использует нормальный механизм слияния, поэтому оно может быть передано GUI-инструменту слияния, чтобы помочь вам в решении проблем.

Когда вы закончите разрешение эффектов патча, MQ обновит ваш патч, основанный на результате слияния.

В конце этого процесса, репозиторий будет иметь одну дополнительную голову от старой очереди патчей, а копия старой очереди патч будет лежать в .hg/patches.N. Вы можете удалить дополнительную голову с помощью hg qpop -a -n patches.N или hg strip. Вы можете удалить .hg/patches.N когда вы уверены, что вам она больше не нужна в качестве резервной копии.

12.10. Идентификация патчей

Команды MQ, которые работают с патчами позволяют ссылаться на патч либо используя его имя или номер. По имени достаточно очевидно; передать имя foo.patch команде qpush, например, и она будет вставлять и применять патчи до foo.patch.

Для сокращения, вы можете обратиться к патчу с использованием имени и цифрового смещения; foo.patch-2 означает «второй патч перед foo.patch», а bar.patch+4 означает «четвёртый патч после bar.patch».

Ссылка на патч по индексу не сильно отличается. Первый патч напечатаны в выходе qseries это нулевой патч нулю (да, это один из тех систем отсчёта, которые начинаются с нуля); второй патч 1, и так далее.

MQ также позволяет легко работать с патчами, как вы используете нормальные команды Mercurial команд. Каждая команда, которая принимает id ревизии также примет название применяемого патч. MQ увеличивает количество тегов в репозитории, как правило по одному для каждого применённого патча. Кроме того, специальные теги qbase и qtip определяют «самый нижний» и «самый верхний» применённые патчи, соответственно.

150

Управление изменениями с Mercurial Queues

Эти дополнительное тегирование нормальными тегами Mercurial делает возможность внесения патчей еще более легким.

• Хотите отправить по email patchbomb с вашей последней серией патчей?

hg email qbase:qtip

(Не знаете, что такое «patchbombing»? Смотрите раздел Раздел 14.4, «Отправить изменений по электронной почте с расширением patchbomb».)

• Нужно, увидеть все патчи начиная с foo.patch которые коснулись файлов в подкаталоге вашего дерева?

hg log -r foo.patch:qtip subdir

Потому что MQ делает имена патчей доступными для остальных команд Mercurial через обычный внутренний механизм тегов, вам не нужно вводить полное имя файла с патчем, если вы хотите идентифицировать его по имени.

Другим полезным следствием представления патчей именами тегов является то, что когда вы выполните команду hg log, она будет отображать название патча, как тег, просто как часть нормального вывода. Это позволяет визуально различать применённые патчи от лежащие в основе «обычных» ревизий. В следующем примере показано несколько простых команд Mercurial использующихся с применёнными патчами.

$ hg qapplied first.patch second.patch

$ hg log -r qbase:qtip

changeset:

1:8bd990ad127b

tag:

first.patch

tag:

qbase

user:

Bryan O'Sullivan <bos@serpentine.com>

date:

Thu Feb 02 14:09:58 2012 +0000

summary:

[mq]: first.patch

changeset:

2:ce57e98425d7

tag:

qtip

tag:

second.patch

tag:

tip

user:

Bryan O'Sullivan <bos@serpentine.com>

date:

Thu Feb 02 14:09:59 2012 +0000

summary:

[mq]: second.patch

$ hg export second.patch

#HG changeset patch

#User Bryan O'Sullivan <bos@serpentine.com>

#Date 1328191799 0

#Node ID ce57e98425d79f974ee096cc6fdf4cc5e4b55918

#Parent 8bd990ad127bfbc3153a923091f86021aa7a7818 [mq]: second.patch

diff -r 8bd990ad127b -r ce57e98425d7 other.c

--- /dev/null Thu Jan 01 00:00:00 1970 +0000

+++ b/other.c Thu Feb 02 14:09:59 2012 +0000 @@ -0,0 +1,1 @@

+double u;

12.11. Полезные вещи, которые необходимо знать

Есть ряд аспектов использования MQ, которые не вписываются аккуратно в отдельные разделы, но их хорошо бы знать. Вот они, в одном месте.

Обычно, когда вы применяете к патчу qpop и потом qpush, ревизия представляющая патч после извлечения/ вставки будет иметь другой идентификатор, чем ревизия, которые представляла патч ранее. Смотрите раздел Раздел B.1.14, «qpush — вставляет патчи в стек» для информации о том, почему так происходит.

151

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]