Не очевидно предложить простые релевантные примеры, и этот комментарий лучше всего подытоживает:
Если изменения близки, то тривиальные разрешения болеевероятно, будут правильными (потому что те, которые являются неправильными, с большей вероятностью касаются одних и тех же частей кода и, следовательно, приводят к нетривиальным конфликтам), и в тех немногих случаях, когда это не так, проблема проявится относительно быстровероятно, очевидным образом.
[Это в основном то, что иллюстрирует ваш пример]
Но обнаружение семантических конфликтов, вызванных слиянием между изменениями в сильно разделенных областях кода, скорее всего, потребует удержания большего количествапрограмма в вашей голове, чем большинство программистов - или в проектах размером с ядро, чем любой программист.
Так что даже если вы просматривали эти 3-сторонние различия вручную, это было бы сравнительно бесполезным упражнением: усилиебыло бы очень непропорционально увеличению уверенности.
На самом деле, я бы сказал, что слияние - это красная сельдь:
этот вид семантического столкновения между несопоставимыми, но взаимозависимыми частями кода неизбеженмомент, когда они могут развиваться отдельно.
Как организован этот параллельный процесс разработки - DVCS;ЦВК;тарболы и патчи;все редактируют одни и те же файлы на общем сетевом ресурсе - это не имеет никакого значения.
Слияние не вызывает семантических столкновений, программирование вызывает семантические столкновения.
В другихИными словами, реальный случай семантических конфликтов, с которыми я столкнулся в реальном коде после слияния, был не простым, а довольно сложным.
Это, как говорится, простейший пример, проиллюстрированный МартиномФаулер в своей статье Feature Branch - это метод переименования:
Проблема, о которой я больше всего беспокоюсь, - это семантический конфликт.
Простой пример этого заключается в том, что если профессор Plum изменит имяметода, который вызывает код Преподобного Грина.Инструменты рефакторинга позволяют вам безопасно переименовывать метод, но только на основе кода.
Так что, если G1-6 содержит новый код, вызывающий foo, профессор Плам не может сказать в своей базе кода, поскольку у него его нет.Вы узнаете только о большом слиянии.
Переименование функции является относительно очевидным случаем семантического конфликта.
На практике они могут быть гораздо более тонкими.
Тестыявляются ключом к их обнаружению, но чем больше кода для слияния, тем выше вероятность возникновения конфликтов и тем сложнее их устранить .
Это риск возникновения конфликтов, особенно семантических конфликтов, что делает большие слияния страшными.
Как Оле Линж упоминает в его ответ (голосование выше), Мартин Фаулер написал сегодня (время этого редактирования) пост о «семантическом конфликте», включая следующую иллюстрацию:
Опять же, это основано на переименовании функции, хотя и в более тонком случаена основе внутреннего рефакторинга функции упоминаются:
Простейшим примером является переименование функции.
Скажем, я думаю, что метод clcBl
будет проще работатьс, если бы это называлось calculateBill
.
Итак, первое, что важно, это то, что, несмотря на всю мощь вашего инструментария, он защитит вас только от текстовых конфликтов.
Однако есть пара стратегий, которые могут существенно помочьмы имеем с ними дело
- Первый из них - SelfTestingCode .Тесты эффективно проверяют наш код, чтобы увидеть, соответствуют ли его представления о семантике кода тому, что код делает на самом деле
- Другой способ, который помогает, - это объединение чаще
Часто людиПопытайтесь обосновать DVCS, основываясь на том, как они облегчают разветвление функций.Но это не касается вопросов семантических конфликтов.
Если вашфункции создаются быстро, в течение нескольких дней, и тогда вы столкнетесь с менее семантическими конфликтами (и если меньше, чем один день, то по сути это то же самое, что и CI).Однако мы не часто видим такие короткие ветки.
Я думаю, что нужно найти золотую середину между ветвями, снятыми живыми объектами, и ветвями объектов.
И объединение часто является ключевым, если у вас есть группа разработчиков на та же ветвь функции .