Как управлять параллельной разработкой с Mercurial? - PullRequest
17 голосов
/ 15 сентября 2010

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

Прежде всего, я говорю о разных изменениях для одного и того же проекта, так что, пожалуйста, не делайте подпунктов.

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

Это тривиально, если (исправление) B зависит от A. Вы просто ci A, а затем c B.

Мой вопрос заключается в том, что делать, когда они независимы (или, по крайней мере, кажется сейчас).

Я могу думать о следующих путях:

  1. Используйте отдельный клон для B.
  2. Использовать анонимные или именованные ветви или закладки в одном и том же хранилище.
  3. Используйте MQ (с патчем B поверх A).
  4. Используйте разветвленный MQ (я объясню позже).
  5. Использовать несколько MQ (с версии 1.6)

1 и 2 освещены в превосходном блоге @Steve Losh, связанном с слегка связанным вопросом .

Одним огромным преимуществом 1 по сравнению с другими вариантами является то, что он не требует какой-либо перестройки, когда вы переключаетесь с работы над одной вещью на другую, потому что файлы физически разделены и независимы. Так что это действительно единственный выбор, если, например, A и / или B касаются заголовочного файла, который определяет логическое состояние с тремя состояниями и включается в тысячи файлов C (не говорите, что вы не видели такой устаревший код база).

3, вероятно, самый простой (с точки зрения настройки и накладных расходов), и вы можете изменить порядок A и B, если B - небольшое и / или срочное исправление. Однако это может быть сложно, если A и B касаются одного и того же файла (ов). Легко исправить фрагменты патчей, которые не удалось применить, если изменения A и B ортогональны в одном и том же файле (ах), но концептуально это все еще немного рискованно.

4 может вызвать у вас головокружение, но это самый мощный, гибкий и масштабируемый способ. Я по умолчанию hg qinit с -c, так как я хочу пометить исправления в процессе работы и протолкнуть / вытянуть их, но требуется концептуальный скачок, чтобы понять, что вы также можете переходить в MQ репо. Вот шаги (mq = hg --mq):

  1. hg qnew bugA; внести изменения для A; hg qref
  2. mq branch branchA; hg qci
  3. hg qpop; mq up -rtip^
  4. hg qnew bugB; внести изменения для B; hg qref
  5. mq branch branchB; hg qci
  6. Чтобы снова поработать над A: hg qpop; mq up branchA; hg qpush

Кажется сумасшедшим делать так много шагов, и всякий раз, когда вам нужно сменить работу, вы должны hg qci; hg qpop; mq up <branch>; hg qpush. Но учтите следующее: у вас есть несколько именованных веток релиза в одном и том же репозитории, и вам нужно одновременно работать над несколькими проектами и исправлять ошибки для всех из них (вам лучше получить гарантированный бонус за этот вид работы). Вы очень скоро потеряетесь с другими подходами.

Теперь, мои друзья-любители hg, есть ли другие / лучшие альтернативы?


(ОБНОВЛЕНИЕ) qqueue почти делает № 4 устаревшим. См. Элегантное описание Стива Лоша здесь .

Ответы [ 3 ]

7 голосов
/ 16 сентября 2010

Я бы всегда использовал именованные ветви, потому что это позволяет Mercurial выполнять свою работу: сохранять историю вашего проекта и помнить, почему вы сделали какие изменения в каком порядке в вашем исходном коде. Если у вас на диске один клон или два, как правило, легко, учитывая мой стиль работы, по крайней мере:

  1. Нет ли в вашем проекте процесса сборки, чтобы вы могли тестировать и запускать программы прямо из исходного кода? Тогда у меня будет соблазн иметь только одного клона и hg up туда-сюда, когда мне нужно будет работать над другой веткой.

  2. Но если у вас есть buildout, virtualenv или другая структура, которая создается и которая может расходиться между двумя ветвями, тогда выполните hg up, тогда ожидание повторного запуска процесса сборки может быть большая боль, особенно если такие вещи, как создание образца базы данных. В этом случае я бы определенно использовал два клона, один сидящий на кончике ствола, а другой сидящий на кончике ветки аварийного признака.

3 голосов
/ 30 октября 2010

Кажется, что нет больше или лучше, чем те, которые я перечислил в вопросе. И вот они снова.

  1. Используйте один клон на проект.
    • Плюсы: полное разделение, поэтому нет необходимости перестраивать при переключении проектов.
    • Минусы: набор инструментов должен переключаться между двумя клонами.
  2. Использовать анонимные или именованные ветви или закладки в одном и том же хранилище.
    • Плюсы: стандартная практика hg (или любая DVCS); чисто и ясно.
    • Минусы: необходимо зафиксировать перед переключением и перестроить после.
  3. Используйте MQ с одним патчем (или несколькими последовательными патчами) на проект.
    • Плюсы: просто и легко.
    • Минусы: необходимо qrefresh до переключения и перестроить после; сложно и рискованно, если проекты не ортогональны.
  4. Используйте одну ветку MQ (или qqueue в 1.6+) на проект.
    • Плюсы: сверхгибкий и масштабируемый (для количества одновременных проектов)
    • Минусы: необходимо qrefresh и qcommit до переключения и перестроить после; чувствует себя сложным.

Как всегда, серебряной пули нет, поэтому выбирайте подходящую для работы.


(ОБНОВЛЕНИЕ) Для всех, кто влюблен в MQ, использование MQ поверх обычных веток (# 2 + # 3), вероятно, является наиболее распространенной и предпочтительной практикой.

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

hg qnew; {coding}; hg qrefresh; {repeat}
hg qfinish -a
hg update -r <branch/bookmark/rev>
hg qimport -r <rev>; {repeat}

Для последнего шага, qimport должен добавить опцию -a, чтобы импортировать строку наборов изменений сразу. Я надеюсь Мейстер Гайслер замечает это:)

1 голос
/ 30 сентября 2010

Таким образом, вопрос в том, что в тот момент, когда вам говорят прекратить работу над функцией A и начать независимую функцию B, какие есть альтернативные варианты для: Как управлять параллельной разработкой с помощью Mercurial?

Давайте посмотрим на проблему с удаленным параллелизмом, так же, как вы пишете многопоточный код - определите простой рабочий процесс для решения любой заданной вам проблемы и примените его к каждой проблеме.Mercurial присоединится к работе, как только это будет сделано.Таким образом, программист A будет работать над функцией A. Программист B будет работать над функцией B. Обе эти вещи просто оказываются вами.(Если бы у нас был многоядерный мозг:)

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

Я согласен с мнением Брэндона, но мне интересно, не заметил ли он, что функция А не была протестирована?В худшем случае код компилируется и проходит модульные тесты, , но некоторые методы реализуют предыдущие требования, а некоторые методы реализуют новые. Разница с предыдущей регистрацией - это инструмент, который я бы использовал дляпомогите мне вернуться к работе с функцией A.

Является ли ваш код для функции A в тот момент, когда вы обычно проверяете его? Переключение с функции A на работу с функцией B непричина для передачи кода в голову или в филиал.Только проверяйте код, который компилирует и проходит ваши тесты. Моя причина в том, что если программисту C нужно запустить функцию C, новая проверка этой ветки больше не является лучшим местом для старта. Поддержание здорового состояния ваших веток означает, что вы можете быстро реагировать с более надежной ошибкойисправления.

Цель состоит в том, чтобы ваш (проверенный и проверенный) код работал, и вы хотите, чтобы весь ваш код в конечном итоге сливался с головой (ваших ветвей разработки и предыдущих версий).Суть в том, что я видел неэффективное использование ветвлений: код становится устаревшим, а затем не используется, объединение становится сложнее, чем исходная проблема.

Только ваш вариант 1 имеет смысл для меня.В общем:

  1. Вы должны подумать, что ваш код работает до того, как его увидит кто-то другой.
  2. Подарите голову над веткой.
  3. Ветка и регистрация, есликто-то другой обнаруживает проблему.
  4. Ветка, если вашей автоматизированной системе или тестерам нужен только ваш код.
  5. Ветка, если вы являетесь частью команды, работающей над проблемой.Считайте это главой, см. 1-4.

За исключением файлов конфигурации, процессы сборки должны быть проверкой и одной командой сборки.Переключение между клонами должно быть не более сложным, чем присоединение к проекту нового программиста.(Я признаю, что мой проект нуждается в некоторой работе здесь.)

...