Как следует использовать рабочий процесс svnmerge с Mercurial?

svnmerge помогает заблокировать некоторые ревизии из определенной ветки. Как этого добиться с помощью Mercurial?


person user134843    schedule 08.07.2009    source источник
comment
Вы можете быть более конкретными? Mercurial обрабатывает все это совершенно иначе, чем svn (все вещи DVCS, вы знаете), поэтому, вероятно, будет легче ответить на ваш вопрос, если вы укажете такие вещи, как: Как размещается ваш репозиторий, у многих ли людей есть доступ для записи, как вы обычно объединить, какие вещи вы хотите заблокировать и т. д.   -  person balpha    schedule 08.07.2009
comment
Я не вижу ничего расплывчатого в вопросе. Я имею в виду наиболее распространенный рабочий процесс: есть ствол, который время от времени помечается релизами. Каждый выпуск порождает соответствующую ветку исправления ошибок, т.е. когда 1.0 помечен, соответствующая ветка 1.0-fixes создается немедленно. Когда исправление фиксируется в основной ветке, необходимо в каждом конкретном случае решать, переносить ли это исправление из основной ветки в конкретную ветку исправлений выпуска. svnmerge прекрасно это автоматизирует.   -  person user134843    schedule 09.07.2009


Ответы (1)


То, что Subversion называет слиянием, сильно отличается от того, что слияние в Mercurial. Операция, выполняемая svnmerge или svn merge, в других системах управления версиями обычно называется «вишенкой». По сути, он создает новую фиксацию, которая является копией исходного набора изменений в целевой ветке. В Mercurial это можно сделать с помощью расширения трансплантата.

Этот метод менее популярен в DVCS по сравнению с обычным слиянием, поскольку он создает несколько головок, которые труднее поддерживать. Вот как вы его использовали бы и как бы выглядел результат:

$ hg checkout -r 8
$ hg branch release
$ hg transplant 10
applying 8ba2867cf974
8ba2867cf974 transplanted to 1f5920f61c94

7---8---9---A [default]
     \
      B [release]

Здесь у вас есть коммит A, который исправляет ошибку в стволе, и вы hg transplant его выпустите, создав новый коммит B, который содержит те же изменения, что и A, но с другими родителями.

Альтернативный подход - не использовать трансплантат и возвращать только исправления в ветку выпуска. Вы должны создать новую ветку выпуска и внести в нее исправления, а затем объединить ветку выпуска с веткой по умолчанию. Это выглядело бы так:

$ hg checkout -r 8
$ hg branch release
... fix fix fix ...
$ hg commit -m"Make fix A"
$ hg checkout -r 9
$ hg merge release
1 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
$ hg commit -m"Merged release branch"

7---8---9---B- [default]
     \     /
      A---- [release]

Здесь B - фиксация слияния. Он не имеет связанных с ним «лишних» изменений (если не было разрешенных конфликтов) и имеет специальное свойство отмечать ветвь выпуска как объединенную с ветвью по умолчанию на этом этапе. Есть только один реальный набор изменений, который исправляет ошибку - помеченный «A» - хотя, конечно, сами изменения также находятся в ветке по умолчанию.

Преимущество такого подхода:

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

Обычно вы отмечаете ветку выпуска «v1.1» или что-то еще в соответствующем месте, чтобы знать, откуда пришел этот выпуск.

К недостаткам такого подхода относятся:

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

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

Вторая проблема возникает, если, например, у вас есть «аварийный» патч к выпускной версии, который устраняет или устраняет ошибку, но требует более крупного исправления по умолчанию для устранения основной проблемы. В этом случае вам придется объединить релиз, а затем создать новую явную фиксацию, чтобы «отменить» фиксацию, которую вы не хотели.

Эта практика в некотором смысле имеет те же преимущества, что и svn merge. Если вы объединяете изменения выборочно от ствола к выпуску, вы должны помнить ревизии, которые вы слили (при условии, что вы не объединяете все стволы). svn merge устанавливает свойства svn: mergeinfo, но их отслеживание может вызвать проблемы, к тому же вам нужно внимательно проверить журналы, чтобы сказать: «О, да, я включил это исправление в релиз ".

Если вы svn-merge всей ветки выпуска в магистраль, когда у вас есть исправление, нет необходимости помнить, какие ревизии были объединены.

person richq    schedule 09.07.2009
comment
Во-первых, спасибо за ответ. Re: Этот метод менее популярен в DVCS по сравнению с обычным слиянием, поскольку он создает несколько головок, которые труднее поддерживать - как тогда проекты, использующие DVCS, управляют ветвями обслуживания релизов? - person user134843; 13.07.2009