Я бы предположил, что именно ваш подход к этим библиотекам вызывает ваши проблемы. Вы можете изменить это, если начнете думать о библиотеках как об отдельных проектах. Думайте о них как о своих собственных причинах существования, своем собственном дизайне и своих собственных циклах выпуска, точно так же, как сторонние библиотеки, которые вы можете использовать для модульного тестирования, чтения XML, доступа к БД и т. Д.
Конечно, у вас будут регулярные случаи, когда функция в проекте требует новой функции в библиотеке. Реализация библиотечной функции и использование библиотечной функции - это две независимые задачи - они могут быть одной бизнес-задачей, но это две задачи разработки. Нет необходимости тесно связывать эти два действия только потому, что именно так и поступило задание. Извлеките библиотеку, измените ее, отпустите, затем извлеките ваш проект и используйте новый выпуск библиотеки в вашем проекте.
Я твердо убежден, что разделение библиотек на свои собственные стволы - это хорошо - я не могу этого вынести, когда вижу несколько независимо выпускаемых проектов под одной стволой. Он пахнет плохим дизайном и загнан в угол разработкой. Но чтобы выделить их, вы должны иметь возможность выпускать каждый проект независимо - для меня это то, что наличие нескольких проектов означает . Но это не сложно сделать:
Сначала проект использует внешние элементы для ссылки на конкретную выпущенную версию библиотеки. Это единственный способ, которым проект ссылается на библиотеку. Это означает, что разработчики могут создать новую версию библиотеки, не нарушая ни один из проектов, использующих ее, поскольку все проекты будут ссылаться на предыдущую версию. Проекты получают контроль, когда они хотят ввести новые версии библиотек - разработчики могут выбирать, когда они хотят приложить усилия к тестированию своего кода с новой версией, и когда взять на себя труд исправления любых проблем сборки новой библиотеки вводит.
Когда вы явно изменяете версии библиотеки, подобные этой, вы также получаете запись в своем проекте, которая говорит: «Я сейчас использую эту версию библиотеки X», которая дает вам хорошее представление о история в вашем проекте относительно того, когда что-то работало и когда именно все изменилось.
Теперь, конечно, все это хорошо в теории, но на практике разработчикам иногда приходится ссылаться на нестабильные и незаконченные версии библиотеки. Это нормально - разработчик всегда может переключить свою рабочую копию, чтобы она указывала на ствол библиотеки вместо тега или на какую-то ветку разработки, и использовать оттуда код (даже работать там, если нужно, бррр). Переключатель - это просто локальное редактирование, поэтому он не повлияет на зафиксированный код. Если разработка проекта происходит в нестабильной ветке, вы можете решить сделать коммутатор более постоянным, изменив ссылку на внешние ресурсы до тех пор, пока ветвь не будет готова к реинтеграции, но это обычно не делается без явной причины.
И, наконец, ветвление и тегирование вашего проекта становится простым случаем создания ветки или тега вашего основного проекта - и все. Не нужно беспокоиться о ветвлении библиотек - они заботятся о себе. Процесс внесения изменений в библиотеку не меняет того, находится ли проект в стволе, в ветке разработки или в техническом выпуске. И ваши библиотеки могут сами иметь ветви разработки, полностью независимые от основных проектов, а также от нескольких поддерживаемых версий и т. Д., Вплоть до любого уровня сложности, который вам необходим и может поддерживаться.
Используя внешние элементы в вашей внешней линии или ветви разработки, вы можете получить единую проверку, которая создаст ваше рабочее пространство в любой структуре, которая вам нужна. Поскольку все библиотеки находятся в главном корне, вы можете иметь несколько проверок нескольких версий без столкновений в сборке.
Я обнаружил, что эта система работает довольно хорошо, и после перемещения рабочих мест в такое место, где это не работает, я испытываю тоску по предыдущему способу работы. Есть проблемы, в основном связанные с библиотеками, в зависимости от того, есть ли рекурсивные внешние или нет. Мое предположение заключается в том, чтобы идти рекурсивно, если это не вызывает проблемы (или чрезмерной боли), а затем перейти к «вырожденной» модели, где проект должен знать об определенных «глубоких» зависимостях, даже если он не использует их напрямую. Кроме того, решите, куда вы будете помещать свои определения externals и придерживайтесь его, нет ничего более раздражающего, чем поиск этих свойств svn: externals в случайных папках в разных проектах. Положить их на корень ствола можно.