Как разрешить конфликт дерева SVN

Я читал в течение нескольких дней, пытаясь найти способ разрешить конфликты деревьев с помощью tortiseSVN 1.8. У меня есть две ветки от ствола:

  • филиалы/3.1
  • филиалы/3.2

Опять же, обе эти ветви были вне ствола. Мы не занимаемся «основной» разработкой на магистрали. Я пытаюсь объединить изменения из нашей ветки 3.1 в нашу ветку 3.2.

Код в версии 3.1 подвергся некоторому рефакторингу, и многие папки, существовавшие в ветке 3.2, больше не существуют в ветке 3.1. Кроме того, есть новая работа по добавлению новой папки в 3.2. Проблема в том, что конфликт дерева не дает мне возможности разрешить конфликты, а только позволяет мне принять рабочую копию. Это кажется серьезным недостатком. Мы много занимаемся рефакторингом, и я ищу процесс, с помощью которого мы могли бы интегрировать изменения в ветке более раннего выпуска в ветку более позднего выпуска.

Может ли кто-нибудь сказать мне лучший способ справиться с этим?


person user2457075    schedule 24.11.2014    source источник


Ответы (1)


Чтобы слияние заработало, вам нужны две вещи:

  • Вам нужна общая родословная между двумя ветвями.
  • Если вы синхронизируете две ветки, вам нужно регулярно объединять их. Например, я предполагаю, что вся работа над 3.1 должна быть в 3.2. Поскольку вы работаете в обеих ветках, вы должны были объединить свои изменения 3.1 с 3.2.

Конфликты слияния возникают из-за того, что слияние представляет собой трехстороннее сравнение. Два потока разработки (поток разработки может относиться к ветви или стволу) сравниваются друг с другом и со своим последним общим предком. Представьте себе файл, в котором строка №100 была изменена в обоих потоках разработки. Слияние одного с другим приведет к конфликту.

Subversion различает не только файлы, но и каталоги. Если я переименую файл в одном потоке разработки (или перемещу его) и сделаю слияние, он будет переименован (или перемещен) в другом потоке разработки. Если я удалю или добавлю файл в один поток разработки и объединим его, он будет удален или добавлен и в другом потоке разработки.

В Subversion может произойти конфликт дерева, если я сделаю два разных действия с одним и тем же файлом в двух потоках разработки. Например, я переименовываю файл и на ветке 3.1, и на 3.2. Даже если я переименую их в одно и то же имя, Subversion воспримет это как конфликт.


Чтобы предотвратить повторение вашей катастрофы: Убедитесь, что ваши две ветки имеют одну и ту же родословную. Почему бы не разветвить 3.2 из ветки 3.1 или, по крайней мере, не интегрировать ветку 3.1 обратно в магистраль перед ответвлением 3.2. Subversion обычно довольно хорошо отслеживает историю, но вам нужно убедиться, что ветки имеют общую историю.

Другой - регулярное слияние. Вам необходимо регулярно объединять ветку 3.1 с веткой 3.2 — возможно, даже каждый день. Это гарантирует, что люди, работающие над веткой 3.2, получат необходимые им изменения в 3.1 и не будут дублировать работу. Постоянное слияние также сохраняет небольшие изменения, а когда возникают конфликты слияния, с ними намного проще справиться. Помните команду svn mergeinfo, которая может сообщить вам, что уже было объединено в 3.2, а что в 3.1 еще нужно объединить. Вы всегда можете использовать параметр --record-only, чтобы предотвратить рассмотрение конкретной версии для будущего слияния. Например, вы исправляете ошибку в обеих ветках, вы используете --record-only, чтобы убедиться, что исправление в 3.1 не сделано в 3.2. Или, если вы сделали изменение в 3.1, которое вы не хотите в 3.2, выполнение --record-only не позволит вам рассмотреть это изменение в ветке 3.2 при следующем слиянии.


Что делать сейчас? Вам нужно распутать свою работу. Посмотрите на svn log между двумя ветвями. Если вы видите исправление ошибки в обеих ветках, используйте svn merge --record-only, чтобы сообщить Subversion, что конкретное изменение в ветке 3.1 также было сделано (хотя и вручную) в ветке 3.2. Посмотрите на перемещение и переименование файлов и посмотрите, как они выполнялись в каждой ветке.

После того, как вы это сделаете, объедините изменения в 3.1 и 3.2 по несколько ревизий за раз, вишневое слияние. Убедитесь, что изменения в 3.1 — это то, что вам нужно в 3.2.

Это долгий процесс, но вы должны это сделать. Используйте это как урок, чтобы улучшить процесс разработки.


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

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

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

Релиз делается на ветке. Если мы найдем ошибку, мы исправим ее в ветке, а затем только объединим эту ревизию с основной веткой (если эта ошибка также находится в основной ветке). После выпуска ветвь блокируется. Если нам нужно сделать исправление, мы можем повторно использовать эту ветку для исправления.

Иногда у нас есть ветви функций. Когда мы это делаем, я удостоверяюсь, что мы постоянно сливаем поток разработки с этой функциональной веткой. Таким образом, когда мы, наконец, реинтегрируем эту функцию обратно в магистраль, у нас почти не будет конфликтов.

Сводя ветвление к минимуму и отслеживая, откуда мы переходим, и выполняя постоянные слияния (как в функциональной ветке), мы уменьшили конфликты слияния и больше не сталкиваемся с проблемами, которые когда-то преследовали наши выпуски.

person David W.    schedule 24.11.2014