Возможный дубликат:
я фанат Subversion, почему я должен рассматривать или не рассматривать Mercurial или Git или любой другой DVCS?
Время от времени вы слышите, как кто-то говорит, что распределенное управление версиями (Git, HG) по своей природе лучше, чем централизованное управление версиями (например, SVN), потому что объединение в SVN затруднительно и болезненно. Дело в том, что у меня никогда не было проблем со слиянием в SVN, и, поскольку вы когда-либо слышали это заявление от сторонников DVCS, а не от реальных пользователей SVN, это напоминает мне те противные рекламные ролики на телевидении, где они попытайтесь продать вам то, что вам не нужно, с помощью неуклюжих актеров притворяться, что то, что у вас уже есть и работает просто отлично, невероятно сложно использовать.
И случай использования, который неизменно поднимается, - это повторное объединение филиала, что снова напоминает мне о тех рекламных объявлениях о продуктах-соломочках; если вы знаете, что делаете, вы не должны (и никогда не должны) заново объединять ветку. (Конечно, это трудно сделать, когда ты делаешь что-то принципиально неправильное и глупое!)
Итак, не говоря уже о нелепом сценарии использования, что в объединении SVN по своей сути сложнее, чем в системе DVCS?
Ответы:
Это связано с тем, что в svn отсутствовали надлежащие структуры данных для точного определения последнего общего предка двух ветвей. Это не имеет большого значения для ветви, которая объединяется только один раз, но может вызвать множество ошибочных конфликтов слияния в ситуациях, когда несколько ветвей объединяются несколько раз.
Я не очень внимательно слежу за SVN, но, насколько я понимаю, эти технические проблемы были исправлены в последних версиях. Однако, это не было исправлено достаточно рано, чтобы развеять миф, и люди, которые пробовали DVCS для слияний, придерживались его по другим причинам.
источник
И в этом источник вашей путаницы и всей проблемы в целом.
Вы говорите, что объединение ветвей "в корне неправильно и глупо". Ну, в этом-то и проблема: вы думаете о ветвях как о вещах, которые не следует объединять Зачем? Потому что вы пользователь SVN, который знает, что объединение ветвей сложно . Поэтому вы никогда не делаете этого, и вы поощряете других не делать этого. Вы были обучены избегать слияния; Вы разработали методы, которые используете, чтобы избежать слияния.
Я пользователь Mercurial. Даже на моих собственных проектах, где я единственный разработчик, я сливаю ветви все время . У меня есть ветка релиза, в которую я положил исправление. Ну, я сливаю это обратно в основную линию, чтобы исправить это.
Если бы я использовал SVN, я бы использовал совершенно другую структуру кодовой базы. Зачем? Потому что SVN делает слияния трудными, и поэтому вы разрабатываете идиомы и методы, чтобы избежать сложных слияний.
DVCS упрощают сложные объединения, потому что они являются состоянием по умолчанию . Все более или менее ответвлено в DVCS. Таким образом, вся их структура построена с нуля, чтобы облегчить слияние. Это позволяет вам разрабатывать рабочий процесс, который использует слияние на ежедневной основе, а не рабочий процесс SVN, где вы никогда не используете слияние.
Простой факт заключается в следующем: вы должны подходить к DVCS не так, как SVN. Вы должны использовать подходящие идиомы для этих очень разных типов систем контроля версий. В SVN вы принимаете идиомы, которые не включают слияния, потому что слияния сложны. В DVCS вы принимаете идиомы, которые часто используют слияния, потому что они не имеют большого значения.
Правильный инструмент для правильной работы.
Дело в том, что рабочий процесс, ориентированный на слияние, намного приятнее и проще в использовании, чем рабочий процесс в стиле SVN, где вы не объединяете вещи. Проще увидеть, когда что-то из ветки релиза было перенесено в ветку dev. Проще увидеть различное взаимодействие между ветвями. Легко создавать тестовые ветки для вещей, а затем обрезать их, если тест не работает. И так далее.
На самом деле, Джоэл объясняет это намного лучше, чем я . Вы должны хорошо прочитать это.
источник
В объединении SVN нет ничего сложного ... больше ... если вы следуете правильной философии
То, что я вижу в большинстве других ответов, похоже, пришло от людей, которые давно не пользовались SVN. Как кто-то точно упоминает: «это не было исправлено достаточно рано, чтобы развеять миф».
Из моего текущего опыта использования SVN 1.6 до 1.8 в унаследованном проекте, который я унаследовал недавно, SVN прошел долгий путь к тому, чтобы сделать слияние намного проще. Тем не менее, он не является надежным, и я думаю, что он не так легко переносит пользователей, которые отклоняются от предполагаемого использования.
Хотя я достаточно хорошо знал SVN и в то же время пробовал Mercurial для личных проектов, до этого проекта я никогда не делал много веток в SVN. Было довольно много проб и ошибок, и я получил много неожиданных конфликтов слияния при запуске.
В конечном счете, тем не менее, я понял, что каждый раз, когда у меня возникает одна (или какая-то другая проблема), это происходит потому, что я не все сделал правильно (так называемый «путь SVN» - возможно, правильный способ контроля версий). Я полагаю, что именно в этом и заключается трудность: вы не можете делать что-то, что хотите, неорганизованным образом и ожидать, что SVN будет работать идеально, особенно с объединениями. Слияния требуют строгой дисциплины от пользователей, прежде чем они покажут свою истинную силу.
Вот что я заметил, это строгие рекомендации, если не требования, для чистого использования слияний:
Если вы не будете следовать вышеизложенному, у вас вполне могут возникнуть конфликты. Они всегда решаемы, но не слишком весело проводить время.
О, еще одна вещь о слиянии, где, из всего, что я прочитал и попробовал, SVN действительно отстой: удаленные / перемещенные / переименованные файлы / папки. Очевидно , что SVN все еще не может иметь дело с файлом, который переименовывается, удаляется или перемещается в одной ветви, а его исходная версия изменяется в другой ветви ... и затем объединяется вместе. Он просто не будет знать, куда файл попал одним способом, и «забудет» об изменениях другим способом. Одно изменение явно неразрешимо (вы либо удаляете, либо изменяете файл, но не можете выполнять оба действия), но применение изменений к перемещенным / переименованным файлам должно работать, а это не так. Надеюсь, это скоро исправят.
В общем, легко ли объединить SVN? Я думаю, нет. Конечно, не беззаботно. Это плохо ? Я так не думаю. Он плюет вам в лицо только тогда, когда вы используете его неправильно и не думаете о том, что вы делаете.
Основываясь на этом, я понимаю, почему люди могут предпочесть Mercurial (например), поскольку он немного более снисходительно относится к этим вещам из моего опыта и автоматизировал все с самого начала (по крайней мере, в ранних версиях, с которых я начинал). SVN, тем не менее, догнал немного, так что больше не стоит так сильно ругаться.
источник
Внутренние модели данных принципиально отличаются.
По сути, в SVN, когда вы смотрите на историю ветки, вы видите только то, что произошло в этой ветке. Таким образом, при объединении из ветви
B
в ветвьA
история веткиA
будет содержать один большой коммит, содержащий все изменения, внесенные явно сB
момента его ветвления.В первых версиях SVN, если вам нужно было еще раз объединить ветвь
B
с ветвьюA
, вам пришлось вручную указать, какой диапазон ревизийB
вы хотите объединить, чтобы избежать слияния одних и тех же ревизий дважды. Умный разработчик, конечно, будет использовать сообщение о коммите, например, «Объединено в B: 1234».SVN 1.5 "исправил" это. Но это не изменило, как слияния применяются фундаментально. Он просто добавил некоторые дополнительные метаданные в ветку
A
, сообщив SVN, что редакция 1234 была объединена, и позволила SVN автоматически выбрать правильный диапазон редакций.Но это решение - в основном обходной путь для модели данных, которая принципиально не поддерживает отслеживание того, что было объединено.
Объединение двух ветвей - сравнительно простой пример. Но воображение это более сложный сценарий
A
отtrunk
и сделайте несколько коммитов здесьB
отA
и сделайте несколько коммитов здесьtrunk
иA
B
вtrunk
A
вB
A
вtrunk
B
сtrunk
(это на самом деле ничего не должно делать)Правильная обработка этого с использованием модели метаданных становится чрезвычайно сложной (я не знаю, действительно ли SVN правильно обрабатывает этот сценарий, и я не склонен проверять это).
Обработка этого сценария в git чрезвычайно проста.
В git каждый раз, когда вы делаете коммит, внутренний объект, представляющий этот коммит, содержит ссылку на предыдущий заголовок. Когда вы объединяете ветку, коммит содержит ссылки на предыдущий заголовок всех объединяемых веток (вы можете объединить более одной ветви за раз в git)
Поэтому, когда вы просматриваете историю одного коммита в git, вы можете видеть всю историю, вы можете видеть, когда она была разветвленной, когда она была объединена, и вы можете видеть историю обеих ветвей между ветвлением и слиянием.
Таким образом, при объединении в ветви, которая была частично объединена, очень просто определить, что уже объединено, а что нет.
У меня нет опыта работы с Mercurial, но я подозреваю, что его внутренняя работа похожа на git.
Таким образом, для SVN целью проекта было создание дешевого ветвления. Но в Git это была цель дизайна - сделать слияние дешевым.
Наконец, в прошлый раз, когда я использовал SVN, он не мог обрабатывать слияния, когда файл переименовывался в одной ветви и изменялся в другой.
источник
Я сделал немало SVN-слияний, включая ветки разработки и выпуска. По большому счету я выжил. Слияние всегда сложно, но с DCVS обратная сторона не так уж и плоха - все локально, поэтому просто обновите до известной хорошей версии и продолжайте. В то время как с SVN много событий происходило на стороне сервера, поэтому восстановление было уродливым - обычно это было связано с стиранием локальной копии и проверкой новой чистой ветки, чтобы попробовать ее снова. В моем случае было неплохо - помогает гигабитное соединение с SVN-боксом. Но у нас было несколько подрядчиков, у которых было много проблем с этим, так как они были на медленных соединениях, так что все происходило вечно, включая слияния.
источник
Здесь кроется одна из самых приятных вещей в git. Это не наследование DVCS, это просто то, в чем Git превосходит все. Вы можете объединить определенные ревизии из любой ветви в другую. Он в основном просто берет diff и применяет его к другой ветке, но делает отслеживание и гораздо более автоматическим.
Итак, если у вас есть ветка 2.0 и ветка 3.0 и вы обнаружили ошибку в 2.0, вы можете исправить ее в 2.0 и взять набор ревизий, которые ее разрешают, и объединить только эти ревизии в ветку 3.0. Я не верю, что у SVN есть какой-либо способ сделать это, кроме как вручную брать различия для каждой ревизии и применять их
Конечно, алгоритм автоматического слияния также выглядит более плавным, и git был построен с нуля на модели «сделай ветвь для всех вещей», поэтому ветвление в ней просто очень плавное и легкое. Просто кажется естественным часто ветвиться с тем, насколько легкими являются его ветви
источник