Почему я получаю конфликты деревьев в Subversion?

353

У меня была ветвь функций моего ствола, и я периодически сливал изменения из моего ствола в мою ветку, и все работало нормально. Сегодня я пошел, чтобы слить ветку обратно в ствол, и все файлы, которые были добавлены в мою ствол после создания моей ветки, были помечены как «конфликт дерева». Есть ли способ избежать этого в будущем?

Я не думаю, что они должным образом помечены.

Greg
источник
Можете ли вы дать рецепт для воспроизведения этой проблемы, начиная с пустого хранилища?
Вим Коенен
Я постараюсь найти время сегодня, чтобы сделать новый репозиторий, проверить его, получить те же результаты и опубликовать ответ. Спасибо.
Грег

Ответы:

399

Я нашел решение, прочитав ссылку, которую дал Гари (и я предлагаю пойти по этому пути).

Подводя итоги для разрешения конфликта дерева, фиксирующего ваш рабочий каталог с клиентом SVN 1.6.x, вы можете использовать:

svn resolve --accept working -R .

где .находится каталог в конфликте.

ВНИМАНИЕ : «Подтверждение вашей рабочей директории» означает, что ваша песочница будет той структурой, которую вы фиксируете, поэтому, если, например, вы удалили какой-то файл из вашей песочницы, они будут удалены и из репозитория. Это относится только к конфликтующей директории.

Таким образом, мы предлагаем SVN разрешить конфликт ( --resolve), принимая рабочую копию внутри вашей песочницы ( --accept working), рекурсивно ( -R), начиная с текущего каталога ( .).

В TortoiseSVN, выбрав «Resolved» по щелчку правой кнопкой мыши, фактически решает эту проблему.

gicappa
источник
32
Таким образом, вы предлагаете svn разрешить конфликт (--resolve), принимая рабочую копию внутри вашей песочницы (--accept working), рекурсивно (-R), начиная с текущего каталога (.) HTH
gicappa
22
в TortoiseSvn, выбрав «Resolved» по щелчку правой кнопкой мыши, фактически решает эту проблему.
Понять
40
не слепо ли это принимает рабочую копию? Я имею в виду, что чувствую, что не могу сказать, где существуют проблемы с этими конфликтами, но если я просто разрешу и приму работу, это не просто сотрет работу других людей?
Паррис
10
Одной из причин этого может быть то, svn rm'dчто вам нужен каталог, который, по вашему мнению, больше не нужен, но кто-то еще добавил новый необходимый файл. Когда вы обновляете свою рабочую копию, вы должны получить конфликт дерева. Если вы просто слепо принимаете свое решение (удаляя каталог), то вы будете удалять файл этого человека. Здесь нет волшебной кнопки "поступай правильно". Вы должны понимать, что вы делаете, почему конфликтует с последней версией и как правильно ее решить.
бамбам
5
@TWiStErRob, я бы сказал, что этот признак свидетельствует о проблемах, присущих SVN как инструменту управления версиями. Лично, способ избежать этой проблемы в будущем будет использовать git. Поскольку это скорее всего не практичный вариант для спрашивающего, то лучше всего справиться с ситуацией, описанной в этом ответе.
Джесс Телфорд
59

Subversion 1.6 добавил Tree Conflicts для покрытия конфликтов на уровне каталогов. Хорошим примером может служить случай, когда вы локально удаляете файл, а затем обновление пытается внести изменение текста в этот файл. Другой случай, когда у вас есть subversion Rename файла, который вы редактируете, так как это действие Add / Delete.

В блоге Subversion CollabNet есть отличная статья о конфликтах деревьев .

Gary.Ray
источник
9
Ни один из приведенных вами примеров не относится к моей ситуации. Возможно, мое описание не ясно?
Грег
33

По моему опыту, SVN создает конфликт дерева, КОГДА я удаляю папку. Кажется, нет никаких причин.

Я единственный, кто работает над моим кодом -> удалить каталог -> зафиксировать -> конфликт!

Я не могу дождаться, чтобы переключиться на Git .

Я должен уточнить - я использую Subclipse . Это, наверное, проблема! Снова, я не могу ждать, чтобы переключиться ...

shmimpie
источник
2
Та же проблема с клиентом командной строки SVN, так что это не Eclipse.
дольмен
3
У меня такая же проблема с NetBeans и SVN. Удалить каталог -> конфликт.
Грубер
2
Та же проблема здесь ... очень очень раздражает ... приходится ОБЩАТЬ, обновлять, удалять и фиксировать ...
marcolopes
1
Я обнаружил отличный трюк с IntelliJ Idea, когда у меня возникают конфликты деревьев. Я сохраняю все свои изменения (это то же самое, что создание патча моих изменений, а затем откат их назад). Затем я делаю обновление SVN, чтобы получить последние изменения от Subversion. После этого я отменяю свои изменения (так же, как применение патча) и альт!
Эрхард
1
Кажется, у меня та же проблема с использованием svn client 1.7.9 в Ubuntu 12.04.4 LTS против репозиториев Assembla.
silicrockstar
28

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

Пример:

Слияние / svn / Project / branch / some-branch / Исходники в / svn / Project / trunk ---> Конфликт дерева

Объединить / svn / Project / филиалы / some-branch to / svn / Project / trunk ---> OK

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

Smarb
источник
17

Здесь происходит следующее: вы создаете новый файл в своей стволе, а затем объединяете его со своей веткой. В коммит-слиянии этот файл будет создан и в вашей ветке.

Когда вы объединяете свою ветку обратно в ствол, SVN снова пытается сделать то же самое: он видит, что файл был создан в вашей ветке, и пытается создать его в вашей стволе в коммите слияния, но он уже существует! Это создает конфликт дерева.

Чтобы избежать этого, нужно сделать специальное слияние, реинтеграцию . Вы можете достичь этого с помощью --reintegrateпереключателя.

Вы можете прочитать об этом в документации: http://svnbook.red-bean.com/en/1.7/svn.branchmerge.basicmerging.html#svn.branchemerge.basicmerging.reintegrate

Однако при объединении вашей ветви обратно в ствол базовая математика сильно отличается. Ваша ветвь функций теперь представляет собой путаницу как дублированных изменений ствола, так и изменений частной ветви, так что нет простого непрерывного диапазона ревизий для копирования. Указывая параметр --reintegrate, вы просите Subversion тщательно реплицировать только те изменения, которые уникальны для вашей ветви. (И на самом деле, он делает это, сравнивая последнее ствол дерева с последним деревом ветвей: результирующая разница - это именно ваши изменения веток!)

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

Есть способ обойти это тоже, но я никогда не пробовал. Вы можете прочитать это в этом посте: Реинтеграция ветки Subversion в v1.6

Габор Ангьял
источник
1
Понижено, потому что --reintegrateопция была объявлена ​​устаревшей в Subversion 1.8. Начиная с SVN 1.8, такие слияния выполняются автоматически!
Бахреп
8
Проголосовал, потому что многие люди все еще используют подрывную деятельность <1.8
juacala
Я думаю, что добавление информации о версии SVN к ответу будет в порядке.
Питер Мортенсен
1
1.8 здесь, и это не будет работать без этого решения.
зима
Проголосовал, потому что это отвечает на вопрос, почему это происходит.
Джошуа Бриден
7

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

Использование клиента версии 1.5 и клиента версии 1.6 в одном и том же хранилище может создать такую ​​проблему. (Я только что укусил себя.)

kaleissin
источник
4

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

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

Это может произойти по крайней мере в 1.4 репозиториях, я не уверен, поможет ли здесь слияние, введенное в 1.5.

Ticcie
источник
2

До сегодняшнего дня, по крайней мере 3 месяца назад, я регулярно сталкивался с сотнями конфликтов деревьев при попытке объединить ветку обратно в ствол (используя TortoiseSVN 1.11 ). Будь перебазирован или нет, кстати. Я использую TortoiseSVN начиная с его версии 1, еще в 2004 году, и я постоянно реинтегрировал ветки. Наверное, что-то случилось недавно?

Итак, сегодня я провел этот простой эксперимент и обнаружил, что создает эти сумасшедшие конфликты:

  1. Я раздвоил багажник @ 393;
  2. Я изменял десятки файлов случайным образом, а также создавал новые;
  3. Я совершил. Сейчас @ 395 (коллега раскошелился на 394, чтобы исполнить свое дело).
  4. Затем я попытался реинтегрировать ветку обратно в ствол, только тест; Следуя рекомендациям TortoiseSVN в мастере: «Чтобы объединить все ревизии (реинтегрировать), оставьте это поле пустым». Чтобы добиться этого, я щелкнул правой кнопкой мыши на папке ствола и выбрал «TortoiseSVN> Merge, from / path / to / branch», и я оставил диапазон оборотов пустым , как рекомендовано в диалоговом окне.

Обсуждение: (см. Вложение)

все ревизии ... чего? Мало ли я знал, что клиент, должно быть, имел в виду « все ревизии цели ! О, МОЙ БОГ. Бедный дьявол, ты погиб здесь. Та ветка родилась @ 393, не могли бы вы прочитать свидетельство о рождении, ради бога?Вот почему произошло так много конфликтов: SVN-cli идет на дурацкий взлет из ревизии 1

Разрешение:

  1. Вопреки тому, что советует волшебник, укажите диапазон, который охватывает ВСЕ пересмотры ... жизни филиала! следовательно, 394-ГОЛОВА ;
  2. Теперь снова запустите тест слияния и возьмите сигару. ( см второе приложение).

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

Фабьен Хаддади
источник
1

Я столкнулся с этой проблемой и сегодня, хотя моя конкретная проблема, вероятно, не связана с вашей. Изучив список файлов, я понял, что сделал - я временно использовал файл в одной сборке из другой сборки. Я внес в него множество изменений и не хотел потерять связь с историей SVN, поэтому в своей ветке я переместил файл из папки другой сборки. Это не отслеживается SVN, поэтому похоже, что файл удален, а затем добавлен заново. Это приводит к конфликту деревьев.

Я решил проблему, переместив файл обратно, зафиксировав, а затем объединив свою ветку. Затем я переместил файл обратно потом. :) Это, казалось, добилось цели.

Дейв
источник
1

У меня была аналогичная проблема. Единственное, что на самом деле мне помогло, - это удалить конфликтующие подкаталоги с помощью:

svn delete --force ./SUB_DIR_NAME

Затем скопируйте их снова из другого корневого каталога в рабочую копию, которая имеет их с:

svn copy ROOT_DIR_NAME/SUB_DIR_NAME

Тогда делай

svn cleanup

а также

svn add *

Вы можете получать предупреждения с последним, но просто игнорируйте их и, наконец,

svn ci .
MFH
источник
0

У меня была такая же проблема, и я решил ее заново, выполнив слияние с помощью этих инструкций . По сути, он использует «объединение двух URL» в SVN, чтобы обновить trunkтекущее состояние вашей ветви, не беспокоясь об истории и конфликтах деревьев. Спасло меня от ручного исправления 114 древовидных конфликтов.

Я не уверен, сохраняет ли она историю так, как хотелось бы, но в моем случае это стоило того.

rescdsk
источник
5
История - это то, почему мы используем VCS ... или я что-то упустил?
TWiStErRob
0

Сценарий, с которым я иногда сталкиваюсь:

Предположим, у вас есть ствол, из которого вы создали ветку релиза. После некоторых изменений в стволе (в частности, создания каталога "some-dir"), вы создаете ветку Feature / Fix, которую вы хотите позже объединить с веткой Release (поскольку изменения были достаточно малы, а функция / Fix важна для выпуска) ,

trunk -- ... -- create "some-dir" -- ...
     \                                  \-feature/fix branch
      \- release branch

Если вы затем попытаетесь объединить ветку feature / fix непосредственно с веткой release, вы получите конфликт дерева (даже если каталог даже не существовал в ветке feature / fix):

svn status
!     C some-dir
      >   local missing or deleted or moved away, incoming file edit upon merge

Таким образом, вам нужно явно объединить коммиты, которые были сделаны в транке, перед созданием ветки feature / fix, которая создала каталог some-dir, перед слиянием ветки feature / fix.

Я часто забываю об этом, поскольку это не нужно в git.

НАРЭ
источник