Как использовать функциональность Mercurial Merge для отклоненных блоков в очереди исправлений, без устаревшего qsave? - PullRequest
8 голосов
/ 05 августа 2011

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

Допустим, у меня есть 2 патча p1 и p2 (применяются в этом порядке). Теперь я делаю изменения на p1:

hg qnew p1
...
hg qnew p2
...
hg qref
hg com --mq -m"(Commit before reject)"
hg qpop p1
{make change}
hg qref
hg qpush -a

... и p2 не может быть применен.

Стандартный способ теперь заключается в том, чтобы применять отбракованные блоки вручную. я хочу использовать что-то вроде MqMergePatch , что приятно и использует слияние Mercurial - но он основан на устаревшей функции:

hg qsave // deprecated: use "hg rebase" instead

Мой вопрос: как это сделать с hg rebase ?

EDIT

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

Ответы [ 2 ]

15 голосов
/ 05 августа 2011

Предложение использовать hg rebase вводит в заблуждение, я думаю. На странице MqMergePatch говорится, что это модификация MqMerge , которая была техникой переброса ряда патчей поверх новых наборов изменений, извлеченных из других источников.

Однако это включает сохранение копии уже примененной очереди исправлений (это действительно все hg qsave does) и использование сохраненной копии в качестве части ссылки для трехстороннего слияния, которое вызывает перебазирование очереди исправлений. Я делал это сам до того, как включил расширение rebase. Тогда это был просто вопрос переброса первого патча поверх ревизии наконечника, я хотел стать его новым родителем.

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

--- A -------- patch1 --- patch2
     \
      \-- B

В описанной выше ситуации очередь исправлений может быть перебазирована на B с помощью hg rebase достаточно легко (таким образом, предлагается использовать hg rebase), но это не имеет никакого отношения к вашей ситуации.

Подход к вашей ситуации

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

--- A --- patch1           <patch2>
             \
              \-- [changes]

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

Если метод, использующий qsave и qpush -m и т. Д., Предпочтителен для вас ниже, то маловероятно , что qsave будет удалено в ближайшее время, даже если оно устарело .

Вот как бы я справился с описанной выше ситуацией, если бы я действительно хотел воспользоваться преимуществами трехсторонних инструментов слияния:

(TortoisHg 2.x пока не позволяет нам перебазировать очереди патчей, так что это вариант финишного импорта-импорта, который я иногда делаю.)

  • Вместо qrefresh используйте qnew, чтобы внести несохраненные изменения в новый патч:

    --- A --- patch1 --- patch1b        <patch2>
    
  • Завершите эти патчи регулярными наборами изменений:

    --- A --- B --- C        <patch2>
    
  • Обновление набора изменений, к которому patch будет применяться чисто (B), и применить исправление:

    --- A --- B --- patch2
               \
                \-- C
    
  • Перебазировка patch2 поверх C, так что трехстороннее объединение используется для разрешения конфликтов между локальным patch2 и другим C с использованием base B:

    (я должен был бы сделать это в TortoiseHg 2.x, завершив patch2 перед перезагрузкой, а затем импортировав его обратно в очередь.)

    --- A --- B --- C --- patch2
    
  • Импорт B и C в очередь в виде исправлений снова:

    --- A --- patch1 --- patch1b --- patch2
    
  • Pop patch2 и patch1b, а затем сложить patch1b в patch1 (переименовано в patch1new):

    --- A --- patch1new       <patch2>
    

Теперь patch2 будет применяться чисто к patch1new.

1 голос
/ 29 июня 2015

Я недавно работал над расширением, чтобы сделать это, так как я использовал много патчей MQ.Расширение называется qsmooth (поскольку вы «сглаживаете» свои патчи).

Вы можете посмотреть здесь: https://bitbucket.org/jwdevel/qsmooth

В нем используется процедура, очень похожая на процедуру в ответ Джоэла .Я еще почти не использовал его в производстве, но он прошел приличное количество тестов, и я рад получать сообщения об ошибках.

...