svnmerge помогает заблокировать некоторые ревизии из определенной ветки. Как этого добиться с помощью Mercurial?
Как следует использовать рабочий процесс svnmerge с Mercurial?
Ответы (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 всей ветки выпуска в магистраль, когда у вас есть исправление, нет необходимости помнить, какие ревизии были объединены.