Когда-нибудь у вас возникнет конфликт при обновлении/слиянии ваших файлов из хранилища или при переключении рабочей копии на другой URL. Существует два типа конфликтов:
Конфликт файлов возникает, когда двое (или более) разработчиков изменили одни и те же строки файла.
Конфликт деревьев возникает, когда разработчик переместил/переименовал/удалил файл или папку, которые другой разработчик также переместил/переименовал/удалил или же только изменил.
Конфликт в файле происходит, когда несколько разработчиков внесли изменения в одни и те же строки. Subversion не знает ничего о вашем проекте, поэтому разрешение конфликтов ложится на плечи разработчиков. Зона конфликта в текстовом файле отмечена следующим образом:
<<<<<<< имя файла ваши изменения ======= результат автоматического мержа с репозиторием >>>>>>> ревизия
Также, для каждого файла, имеющего конфликты, Subversion создает в том же каталоге три дополнительных файла:
Это ваш файл, каким он был в рабочей копии перед выполнением обновления, т.е. без конфликтных отметок. В этом файле содержатся ваши последние в нём изменения, и ничего другого.
Это файл, который был базовой ревизией перед обновлением вашей рабочей копии, т.е. это тот файл, который был извлечён до того, как вы начали вносить ваши последние изменения.
Это файл, который был получен с сервера клиентом Subversion при обновлении вашей рабочей копии. Этот файл соответствует ведущей (HEAD) ревизии хранилища.
Вы можете либо запустить внешнюю утилиту слияния / редактор конфликтов с помощью <<<<<<<
.
После этого выполните команду filename.ext.mine
и filename.ext.r*
для того, чтобы вы могли зафиксировать ваши изменения.
Если конфликты возникли в двоичных файлах, Subversion не пытается самостоятельно слить эти файлы. Локальный файл остаётся неизменённым (точно таким, как при последнем вашем изменении) и у вас есть файлы filename.ext.r*
. Если вы хотите отменить ваши изменения, и сохранить версию из хранилища, используйте команду 'Убрать изменения'. Если вы хотите сохранить вашу версию и переписать версию в хранилище, используйте команду 'Улажено', после чего зафиксируйте вашу версию.
Вы можете использовать команду 'Улажено' для нескольких файлов, если, после щелчка правой клавишей на родительской папке, выбрать
→ Появится диалог со списком всех конфликтующих файлов в этой папке, и вы сможете выбрать, какие из них пометить как улаженные.Конфликт свойств возникает когда два или более разработчиков изменили одно и то же свойство. Как и содержимое файла, разрешение конфликта может быть выполнено только разработчиками.
Если одно из изменений должно перекрыть другое, то выберите вариант Уладить, применив локальное свойство или Resolve using remote property. Если изменения должны быть слиты, выберите Редактировать свойство вручную, решите каким должно быть значение свойства и отметьте как разрешенный.
Конфликт деревьев возникает, когда разработчик переместил/переименовал/удалил файл или папку, которые другой разработчик также переместил/переименовал/удалил или же только изменил. Есть множество различных ситуаций, которые могут привести к конфликту деревьев, и все они требуют различных шагов для улаживания конфликта.
Когда файл удаляется локально в Subversion, файл также удаляется и в локальной файловой системе, поэтому, даже если он участвует в конфликте деревьев, на нём не может быть показана пометка конфликта и вы не можете щёлкнуть на нём правой кнопкой и уладить конфликт. Воспользуйтесь вместо этого диалогом Проверка на наличие изменений для доступа к опции Редактировать конфликты.
TortoiseSVN может помочь обнаружить подходящее место для слияния изменений, но, возможно, потребуются дополнительные усилия по улаживанию конфликтов. Помните, после обновления рабочая БАЗА всегда содержит ту ревизию каждого элемента, которая была у него в хранилище во время обновления. И когда вы убираете изменение после обновления, оно вернётся к состоянию, каким оно было в хранилище, а не к тому, каким оно было, когда вы начали делать свои локальные изменения.
Разработчик А изменяет Foo.c
и фиксирует это в хранилище.
Одновременно разработчик Б переименовывает Foo.c
в Bar.c
в своей рабочей копии, или просто удаляет Foo.c
или его родительскую папку.
Обновление рабочей копии разработчика Б приводит к конфликту деревьев:
Foo.c
удалён из рабочей копии, но помечен как участвующий в конфликте деревьев.
Если конфликт произошёл из-за переименования, а не из-за удаления, то Bar.c
помечен как добавленный, но он не содержит изменений, выполненных разработчиком А.
Разработчик Б теперь должен решить, оставлять ли изменения разработчика А. В случае переименования файла, он может перенести изменения из Foo.c
в переименованный файл Bar.c
путём слияния. Для простых удалений файлов или папок он может оставить элементы с изменениями разработчика А и отказаться от удаления. Или, пометив конфликт как улаженный и ничего больше не делая, отказаться в итоге от изменений разработчика А.
The conflict edit dialog offers to merge changes if it can find the original file of the renamed Bar.c
. If there are multiple files that are possible move sources, then a button for each of these files is shown which allow you to chose the correct file.
Разработчик А переименовывает Foo.c
в Bar.c
и фиксирует это в хранилище.
Разработчик Б изменяет Foo.c
в своей рабочей копии.
Или в случае переименования папки...
Разработчик А переименовывает родительскую папку FooFolder
в BarFolder
и фиксирует это в хранилище.
Разработчик Б изменяет Foo.c
в своей рабочей копии.
Обновление рабочей копии разработчика Б приводит к конфликту деревьев. Для простого конфликта файлов:
Bar.c
добавлен в рабочую копию как обычный файл.
Foo.c
помечен как добавленный (с историей) и как участвующий в конфликте деревьев.
Для конфликта папок:
BarFolder
добавлена в рабочую копию как обычная папка.
FooFolder
помечена как добавленная (с историей) и как участвующая в конфликте деревьев.
Foo.c
помечен как добавленный.
Теперь разработчик Б должен решить, принять ли проведённую разработчиком А реорганизацию и слить свои изменения с соответствующим файлом в новой структуре, или просто отменить эти изменения и оставить локальный файл.
To merge her local changes with the reshuffle, Developer B must first find out to what filename the conflicted file Foo.c
was renamed/moved in the repository. This can be done by using the log dialog. Then use the button which shows the correct source file to resolve the conflict.
If Developer B decides that A's changes were wrong then she must choose the Mark as resolved button in the conflict editor dialog. This marks the conflicted file/folder as resolved, but Developer A's changes need to be removed by hand. Again the log dialog helps to track down what was moved.
Разработчик А переименовывает Foo.c
в Bar.c
и фиксирует это в хранилище.
Разработчик Б переименовывает Foo.c
в Bix.c
.
Обновление рабочей копии разработчика Б приводит к конфликту деревьев:
Bar.c
помечен как добавленный с историей.
Bar.c
добавлен в рабочую копию со статусом 'нормальный'.
Foo.c
помечен как изменённый и участвующий в конфликте деревьев.
Для улаживания этого конфликта разработчик Б должен выяснить, какое имя получил конфликтующий файл Foo.c
при переименовании/перемещении в хранилище. Это можно сделать при помощи диалога журнала.
Затем разработчик Б должен решить, какое из новых имён файла Foo.c
оставить - то, которое дал разработчик А или то, в которое он переименовал его сам.
После того, как разработчик Б вручную уладил этот конфликт, конфликт деревьев помечается как улаженный при помощи кнопки в диалоге редактирования конфликтов.
Разработчик А, работая в стволе, изменяет Foo.c
и фиксирует это в хранилище.
Разработчик Б, работая в ответвлении, переименовывает Foo.c
в Bar.c
и фиксирует это в хранилище.
Слияние изменений разработчика А в стволе с ответвлением в рабочей копии разработчика Б приводит к конфликту деревьев:
Bar.c
уже в рабочей копии со статусом 'нормальный'.
Foo.c
помечен как отсутствующий и участвующий в конфликте деревьев.
Для улаживания этого конфликта разработчик Б должен пометить файл как улаженный в диалоге редактирования конфликтов, который уберёт его из списка конфликтов. После этого он должен решить, скопировать отсутствующий файл Foo.c
из хранилища в рабочую копию, или слить изменения разработчика А в файле Foo.c
в переименованный Bar.c
, или же проигнорировать изменения, пометив конфликт как улаженный и больше ничего не делая.
Обратите внимание: если вы скопируете отсутствующий файл из хранилища и после этого пометите конфликт как улаженный, то ваша копия будет снова удалена. Сначала вы должны уладить конфликт.
Разработчик A работающий в trunk перемещает Foo.c
в Bar.c
и фиксирует это в хранилище.
Разработчик Б, работая в ответвлении, изменяет Foo.c
и фиксирует это в хранилище.
Разработчик А, работая в стволе, переименовывает родительскую папку FooFolder
в BarFolder
и фиксирует это в хранилище.
Разработчик Б, работая в ответвлении, изменяет Foo.c
в своей рабочей копии.
Слияние изменений разработчика А в стволе с ответвлением в рабочей копии разработчика Б приводит к конфликту деревьев:
Bar.c
помечен как добавленный.
Foo.c
помечен как изменённый и участвующий в конфликте деревьев.
Теперь разработчик Б должен решить, принять ли проведённую разработчиком А реорганизацию и слить свои изменения с соответствующим файлом в новой структуре, или просто отменить эти изменения и оставить локальный файл.
To merge her local changes with the reshuffle, Developer B must first find out to what filename the conflicted file Foo.c
was renamed/moved in the repository. This can be done by using the log dialog for the merge source. The conflict editor only shows the log for the working copy as it does not know which path was used in the merge, so you will have to find that yourself. The changes must then be merged by hand as there is currently no way to automate or even simplify this process. Once the changes have been ported across, the conflicted path is redundant and can be deleted.
If Developer B decides that A's changes were wrong then she must choose the Mark as resolved button in the conflict editor dialog. This marks the conflicted file/folder as resolved, but Developer A's changes need to be removed by hand. Again the log dialog for the merge source helps to track down what was moved.
Разработчик A работающий в trunk перемещает Foo.c
в Bar.c
и фиксирует это в хранилище.
Разработчик B работающий в ответвлении перемещает Foo.c
в Bix.c
и фиксирует это в хранилище.
Слияние изменений разработчика А в стволе с ответвлением в рабочей копии разработчика Б приводит к конфликту деревьев:
Bix.c
помечен как имеющий нормальный (неизменённый) статус.
Bar.c
помечен как добавленный с историей.
Foo.c
помечен как отсутствующий и участвующий в конфликте деревьев.
To resolve this conflict, Developer B has to find out to what filename the conflicted file Foo.c
was renamed/moved in the repository. This can be done by using the log dialog for the merge source.
Затем разработчик Б должен решить, какое из новых имён файла Foo.c
оставить - то, которое дал разработчик А или то, в которое он переименовал его сам.
После того, как разработчик Б вручную уладил этот конфликт, конфликт деревьев помечается как улаженный при помощи кнопки в диалоге редактирования конфликтов.
Существуют и другие случаи помечаемые как конфликты деревьев из-за того, что конфликт затрагивает скорее папку, а не файл. Например, если вы добавите папку с одинаковым именем в ствол и отвлетвление и затем попытаетесь выполнить слияние, то у вас возникнет конфликт деревьев. Если вы хотите исключить созданную папку из слияния, то отметьте конфликт как улаженный. Если же вы хотите использовать папку из источника слияния, то вам необходимо удалить эту папку из назначения и выполнить слияние снова. Если вы столкнулись с чем-то более сложным, то улаживайте конфликт вручную.