... Другой образ мыслей об этом шаблоне - то, что Ваша еженедельная синхронизация соединительной линии для ветвления походит на выполнение svn обновление в рабочей копии, в то время как заключительный шаг слияния походит на выполнение svn фиксация из рабочей копии
Я нахожу этот подход очень непрактичным в больших разработках, по нескольким причинам, главным образом связанным с шагом реинтеграции.
Вместо этого мы делаем то, что мы называем "переветвлением". В этом случае, когда значительный блок магистральных изменений необходим, ответвление новой возможности открыто от текущей соединительной линии, и слияние является всегда нисходящим (Ответвления функции-> соединительная линия-> стабильные ответвления). Это не продвигается, книжные инструкции по SVN и разработчики рассматривают его как дополнительную боль.
Как Вы обрабатываете эту ситуацию?
После исследования:
После множества мозговых штурмов на Visionmap, обсуждений F2F, включая Артема, открытие книжного шкафа SVN и т. Д. - похоже, это невозможно. Функциональная ветка совершенно не похожа на рабочую копию. Единственный рабочий способ обновить его - воссоздать новую ветку, как описано выше.
Мы небольшая компания, поэтому я не известен, если наше решение будет применяться к вашей ситуации. То, что мы делаем, это обрезание открики от багажника до устойчивой ветви. Мы можем сделать это в 2 разных способах: - Действительно нужно исправить, мы сдерживаем только после совершения багажника - Опасное исправление / изменение. Мы ждем несколько дней, пока изменение не будет подтверждено в багажнике, а затем объединяться
с этим непрерывным объединением, мы избегаем тонн конфликтов.
Мои 2 цента.
Из SVN v1.5, слияние выполняется по очереди.Выбор областей для слияния привел бы к тому, что мы разрешили конфликты магистральных ветвей дважды (один раз при слиянии ревизий ствола в FB, и еще раз при обратном слиянии)
Затем вы что-то делаете неправильный!
Давайте посмотрим:
trunk fb
---------\
r1-10 |
r11-20 |
r20-30 |
Обычно, если вы хотите, чтобы изменения были внесены в 11-20, то лучше всего объединить 1-20 в fb и получить все там.
Затем, когда fb будет готов, слейте 20-30, а затем скопируйте fb в транк (без слияния!).
Если вы решили объединить только r11: 20, хорошо, в конце вам нужно будет объединить r1: 10 и r20: 30 , а затем скопировать fb в транк.
Невозможно объединить изменения дважды!
Я предполагаю, что вы, вероятно, делаете следующее:
copy trunk->fb
merge 11:20 -> fb.
merge fb-1:30 -> trunk !!!!! WRONG
Вы не можете этого сделать, потому что вы дважды объедините 11:20. Вы всегда должны объединять код только в одном направлении.
Правильный способ:
copy trunk->fb
merge 1:20 -> fb.
merge 21:30 -> fb (now fb=trunk+feature)
copy fb -> trunk
Редактировать
Итак, правильные шаги следующие:
Создать ветку функции (FB) из магистрали (копировать магистраль в ветку функции с помощью svn-copy)
FB_0 = trunk_0 {{1 }}
Работа над FB.
FB_1 = FB_0 + change_a
Объединить все предстоящие изменения из транка в FB.
trunk_1 = trunk_0 + tr_change_a;
FB_2 = FB_1 + (trunk_1 - trunk_0) == trunk_0 + change_a + tr_change_a
Работа над FB
FB_3 = FB_2 + change_b { {1}}
Объединить все предстоящие не объединенные изменения из магистрали в FB.
trunk_2 = trunk_1 + tr_change_n;
FB_4 = FB_3 + (trunk_2 - trunk_1) == trunk_0 + change_a + change_b + tr_change_a + tr_change_b
На этом этапе у нас есть ветка функций который состоит из всех новых функций и всех изменений в стволе.Поэтому мы просто копируем разницу между двумя ветвями.
trunk_3 = trunk_2 + (FB_4 - trunk_2) = FB_4 = trunk_0 + change_a + change_b + tr_change_a + tr_change_b
Теперь FB удален, поскольку в транке есть все необходимые изменения.
Последний шаг выполняется:
svn merge / path / to / trunk @ LatestRev / path / to / branch / fb @ LatestRev.
svn ci
Или на обычном языке возьмите разницу между стволом и ветвью и поместите их в ствол , сделав их эквивалентными.
Этот шаблон описан в http://svnbook.red-bean.com/en/1.4/svn.branchmerge.commonuses.html#svn.branchmerge.commonuses.patterns.feature
Теперь, если это у вас не работает, то я не понимаю вопроса.
Edit2: Для svn-1.5
При работе с svn-1.5 вы можете выполнить слияние намного проще:
Когда вы работаете над функциональной веткой, вы просто время от времени объединяете изменения:
$ svn merge /path/to/trunk
Solve conflicts
$ svn ci
Это выровняет ваш FB со всеми изменениями в транке. В конце FB вы запускаете эту процедуру еще раз, чтобы убедиться, что все обновлено. Вы переходите в магистраль и запускаете
$ svn merge --reintegrate /path/to/fb
$ svn ci
В последнем не должно быть конфликтов, если вы работаете, как показано.
К сожалению, все упомянутое можно считать хаками. Обновление из ствола в ветке может привести к очень серьезным проблемам при возврате в ствол и открывает возможность для худшего из всех конфликтов - конфликта деревьев. Это происходит потому, что каталоги не рассматриваются как первоклассные граждане. Лучший подход - использовать Mercurial с расширением SVN в качестве стандартного клиента SVN. Это позволит вам продолжать использовать SVN, получая при этом все возможности Mercurial по работе с папками.
Затем на стороне рабочей станции вы можете использовать ряд подходов, которые обеспечивают множество возможностей, подходящих для многих ситуаций, по сравнению с единственной SVN. Вы можете использовать регулярные исправления, очереди исправлений, обновление из локальной копии ствола, не затрагивая общий ствол, и различные другие подходы.
Этот подход позволяет обойти все недостатки SVN. Мне пришлось перейти на этот подход из-за схожих обстоятельств. Даже если вы не будете использовать этот подход немедленно, вы должны по крайней мере попробовать его как можно скорее.
Думаю, мне нужно взять дубинки для @Artyom здесь. Я тоже думаю, что если вам нужно
разрешить конфликты магистральных ветвей дважды
, что-то не так. И я думаю, что аргумент / решение @Artyoms довольно солидный.
Я считаю, что одна из незначительных вещей, которые @Artyom мог бы написать яснее, это то, что в конце, когда вы «копируете» fb
в ствол
, вы не используете svn copy
, но svn merge
(или svn merge --reintegrate
). Это может быть причиной того, что вы не найдете шаблон «копирование-слияние» в Common Branch Patterns .
Поскольку я до сих пор пытаюсь понять, что вы делаете, я не знаю, что еще сказать.
Вот что я слышу:
Вместо этого мы делаем то, что называем «повторное ветвление». В этом случае, когда значительная часть изменений ствола необходимо, открывается новая функциональная ветка из текущего ствола, ...
Теперь у вас есть новая ветка (назовем ее b2), которая эквивалентна стволу, верно? И где «необходим значительный фрагмент изменений ствола»? Я предполагаю, что в fb?
... и слияние всегда вниз (ветки функций -> ствол -> устойчивые ветви).
Но поскольку вы только что создали b2 из транка, нечего слить в транк, не так ли? И вы также не объединяете изменения из b2 в fb (так как это будет то же самое, что объединить транк в fb ...).Так как же «значительные куски изменений» попадают в fb? И когда они там есть, зачем вам объединять их обратно в магистраль (ведь именно отсюда они в первую очередь)?
На самом деле следующие ссылки раздел под названием «Отслеживание слияний вручную» и / или раздел под названием «Слияние одной ветки с другой» , представленный в документации SVN 1.4 (я знаю, вы не используете SVN 1.4, но я считаю, что это применимо в любом случае) в разделе Общее ветвление Шаблоны могут помочь прояснить некоторые вещи. Эти ссылки «отсутствуют» в документации 1.5 (вероятно, из-за новой опции - reintegrate
в merge
).
Кажется, вы действительно дважды объединяете одни и те же изменения, и я действительно думаю, что вам не следует (нужно) этого делать.