SVN → Подключение внешних библиотек

    Итак, сегодня речь пойдет о подключении внешних библиотек (суб-проектов) в основные проекты с использованием Subversion.
    По старой доброй традиции, в качестве клиента для работы с SVN будет использоваться давно полюбившийся нам TortoiseSVN.

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

    Подключение внешних библиотек может оказаться очень полезной «фишкой» системы контроля версий, особенно, когда вы работаете над несколькими проектами, которые используют одну и ту же библиотеку (это может быть что угодно, от класса для работы с БД до системных шаблонов).

    Для примера, давайте определим исходные данные:
    у нас есть два проекта («Один», «Два») и одна библиотека («Library»), которую необходимо внедрить в оба проекта. Пусть у нас будет следующий путь до этой библиотеки: subserver/code/library/trunk.
    Рабочие копии обоих проектов у нас есть. Предположим, что в каждом из них есть папка /libraries/, внутри которой нам нужно создать папку /library/, в которой и будет лежать наша внешняя библиотека.
    Я изначально указываю на то, что библиотека будет лежать в отдельной папке, т.к. свойство svn:externals, которое мы будем использовать, работает только с папками.

    Дальше, все получается очень просто: открываем свойства папки /libraries/ любого из проектов (два проекта описываются исключительно для того, чтобы показать, как работает обновление). Выглядеть оно будет примерно так:



    Нажимаем кнопочку Add..., и видим окно для добавления свойств, примерно следующее:



    В выпадающем списке выбираем пункт svn:externals (первый в списке). Далее нам необходимо прописать значение свойства. Для svn:externals значением является строчка следующего вида:
    Имя-Папки Путь-К-Репозиторию, где для нашего примера имя папки будет: library, а путь к репозиторию будет: subserver/code/library/trunk.
    Дословно наша строчка будет выглядеть так:
    library subserver/code/library/trunk

    Путь к репозиторию можно легко получить, воспользовавшись утилитой Repo-browser, входящий в поставку TortoiseSVN.
    Разделителем может служить один или несколько символов пробела или табуляции. Лично я использую четыре пробела.

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

    Собственно, на этом все нововведения заканчиваются. Сохраняем свойства.
    Далее, нам необходимо сделать Update, чтобы убедиться, что все верно и библиотека успешно загрузится в проект. При этом папка /library/ будет создана автоматически. Если все гладко, делаем Commit, чтобы сохранить свойства папки непосредственно в репозитории проекта. С этого момента, во всех рабочих копиях этого проекта (т.е. у всех разработчиков) нужная библиотека будет подключаться автоматически.

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

    Теперь допустим ситуацию, когда при работе над проектом «Два» нам необходимо изменить что-то в библиотеке. Мы вносим эти изменения непосредственно в файлы, которые физически находятся в папке /libraries/library/. После того, как все изменения были внесены, мы делаем Commit. И изменения автоматически заносятся в репозиторий библиотеки: subserver/code/library/trunk. Если теперь сделать Update проекта «Один», туда будет загружена обновленная версия библиотеки.
    Тут есть тонкий момент относительно комментариев, добавляемых к Commit'у: если изменения касаются и проекта, и библиотеки, то все комментарии запишутся в логи и к проекту, и к библиотеке. Так что я рекомендую сохранять подобные изменения отдельными ревизиями.

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

    И, напоследок, практически цитата из документации: помните, что svn:externals — это свойства папки, таким образом, если ваш проект или внешняя библиотека будут куда-то перемещены (напр. Relocate'ом), пути в свойствах не изменятся автоматически, их нужно будет исправлять вручную.

    Вот, в общем-то, и все, что я хотел вам сегодня поведать.
    Как всегда, с удовольствием почитаю ваши комментарии.
    Поделиться публикацией

    Похожие публикации

    Комментарии 31

      0
      Конечно, очень жаль, что свойство применимо только для директорий. Это делает ее бесполезной для однофайловых внешних проектов.
      Некоторые поправки и дополнения, с Вашего позволения:
      1) При первом update /libraries/ произойдет автоматическое создание директории library т.е. того на что мы ссылались;
      2) если вдруг получилась несовместимая со старыми версиями библиотека, то сопровождать ее лучше с помощью меток (tags), а не веток (branches). Технически - никакой разницы, а вот смысл улучшается.
        0
        Ну, branches VS tags надо обязательно обозреть в ближайшее время, потому что там действительно много аспектов, которые помогут правильно организовать хранение кода.
      • НЛО прилетело и опубликовало эту надпись здесь
          0
          Да, с ревизиями сложно, если предполагается изменять код внешней библиотеки из проекта.

          Странно, что у вас не получается коммитить все вместе. Я перед написанием топика специально проверил, куда попадут комментарии, у меня они попали в оба репозитория. Но коммит прошел отлично. Хотя, может быть это из-за того, что и проект, и библиотека у меня на одном сервере. Ткните меня носом в документацию, где такое написано. Я, в свою очередь, если интересно, могу описать все свои действия и приложить скриншоты, потому что у меня отлично все Commit'ится.
          • НЛО прилетело и опубликовало эту надпись здесь
              0
              Это док к версии 1.0. Текущая версия: 1.4.5.
              Думается мне, в этом и состоит несоответствие...
          0
          Статья про то, как прикрутить externals к текущему репозиторию? Или я что-то упустил?
            0
            неуклюже выразился. Я к тому, что зачем эта заметка нужна и на кого рассчитана? ИМО вольное переложение документации.
              +1
              Так и есть.
              Не читайте ее больше (:
            –4
            Выбрасывайте свои виндоусы, ставьте git. Жизнь станет милее.
            • НЛО прилетело и опубликовало эту надпись здесь
                +1
                git и под виндоусом есть.
                  0
                  Только работает как-то неспешно =)
                    0
                    Пилят его, авось, со временем допилят. Сделают TortoiseGit и т.д. :)
                    0
                    Вы имеете в виду танцы с Cygwin, или уже есть нормальное решение, а мужики-то не знают?.. :)
                      0
                      http://code.google.com/p/msysgit/
                        0
                        Ухты, будем попробовать, спасибо.
                • НЛО прилетело и опубликовало эту надпись здесь
                    0
                    Ну, мне больше приходится работать с интерпретируемым, а не компилируемым кодом, так что для меня нет проблемы сборки.
                    0
                    Когда идет интенсивная разработка, нескольких проектов, причем Library является частью одного из проектов и тоже развивается, можно попасть в неприятную ситуацию, когда проTAGаная версия отправленая заказчику или даже просто на тестирование, через некоторое время станет некомпилируемой.
                    В этой ситуации надо TAGать также и тот проект который яввляется externals'ом для выпсукаемой версии проекта и менять externals на этот таг.
                    И по хорошему в Ред Буке не делают externals на trunk, его там делают на tag изначально.
                      0
                      Добавлю: если надо добавить более чем одну библиотеку, то при прописывании свойства папки svn:externals нужно указать значение (каждая библиотека с новой строки):

                      library1 http://path-to-library1/
                      library2 http://path-to-library2/
                      library3 http://path-to-library3/
                      


                      Переписывать мануал, так по полной :)
                        0
                        Автор, перезалейте картинки заново, пожалуйста. Слезно умоляем всем отделом. :)
                          +1
                          Картинки перезалил.
                          Но, подозреваю, что за давностью лет этот небольшой мануальчик уже утратил свою актуальность…
                            0
                            Большущее спасибо!!!
                          0
                          Перенёс топик в блог «Разработка» — так вышло…
                            0
                            Не подскажите, что я делаю не так?

                            Делал все по инструкции: прописал в свойстве папки путь к библиотеке, сделал Update, все загрузилось правильно в мою рабочую копию. Но вот Commit не дает сделать — нет такой опции, будто ничего не менялось.

                            Может кто знает что изменилось с 2007 года?
                              0
                              Извиняюсь, все хорошо. Это я ошибся. :)

                              Скажите, а можно эти свойства svn:externals какой-то командой поменять прям на сервере?
                              А то тут возникла задача написать хук, который это делает прям на сервере.
                                +1
                                $ svn help | grep prop
                                   propdel (pdel, pd)
                                   propedit (pedit, pe)
                                   propget (pget, pg)
                                   proplist (plist, pl)
                                   propset (pset, ps)
                                
                                $ svn help propedit
                                $ svn help propset
                              0
                              Не стоит ли этот старый топик перенести в блог «Системы управления версиями»?
                                0
                                Как пожелаете.
                                0
                                и «Нажимаем кнопочку Add...» — а на скрине кнопочка «New...»

                                К слову, топик вполне актуален. Вот, мне пригодился.

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.