Comments 27
Сейчас кто-нибудь напишет «используйте GIT!» :)
Кстати, существует ли в git аналог svn:externals? Как решается проблема подключения общих библиотек?
Кстати, существует ли в git аналог svn:externals? Как решается проблема подключения общих библиотек?
Да, в Git есть Submodules:
markhansen.co.nz/git-repo-inside-git/#submodules
Есть и альтернатива в виде Subtree merges. Подробнее про последний путь тут:
www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html
markhansen.co.nz/git-repo-inside-git/#submodules
Есть и альтернатива в виде Subtree merges. Подробнее про последний путь тут:
www.kernel.org/pub/software/scm/git/docs/howto/using-merge-subtree.html
UFO just landed and posted this here
Разумеется, мы можем работать над всеми проектами/модулями в пределах одного репозитория, но такой подход не лишен недостатков. Например, все разработчики могут загружать к себе в рабочие копии много ненужных изменений. Не получится ограничить доступ разработчикам к тем проектам, к которым у них доступа быть не должно.
/path/to/rep/conf/authz
и настройте для каждого пути свой список доступа.
Если сервер, на который мы ссылаемся, переехал – надо полностью модифицировать репозиторий
svn switch --relocate
/path/to/rep/conf/authz
и настройте для каждого пути свой список доступа.
а как это сделать на одном из онлайновых svn-репозиториев? очевидно, никак. к тому же у одного репозитория на все есть другие недостатки, помимо прав доступа.
svn switch --relocate
речь шла о том, что в истории останется невалидная ссылка на внешний ресурс. то есть совсем о другом речь шла.
я про другие недостатки ничего и не писал.
но процитированное недостатком не является.
судя по тому, что дальше рекомендуют использовать svnadmin dump и подобное, речь шла не об онлайновых репозиториях :)
это для миграции рабочей копии, чтобы checkout заново не делать.
для изменения свойства в предыдущих ревизиях есть svnadmin setrevprop, та черная магия с переписыванием дампа вручную все равно не нужна.
но процитированное недостатком не является.
судя по тому, что дальше рекомендуют использовать svnadmin dump и подобное, речь шла не об онлайновых репозиториях :)
речь шла о том, что в истории останется невалидная ссылка на внешний ресурс. то есть совсем о другом речь шла.
это для миграции рабочей копии, чтобы checkout заново не делать.
для изменения свойства в предыдущих ревизиях есть svnadmin setrevprop, та черная магия с переписыванием дампа вручную все равно не нужна.
Здравствуйте!
Путь через «svnadmin setrevprop» также возможен, но, на мой вгляд, требует больше усилий и занимает больше времени. При таком подходе все равно нужно:
-найти в дампе все проблемные ревизии, где встречаются ссылки на внешний репозиторий
-каждое свойство, которое нужно поменять, скопировать в файл
-поправить ссылку в файле
-применить «svnadmin setrevprop» для каждого свойства
При предложенном мной подходе все изменения делаются по ходу просмотра файла дампа. Количество байт не нужно считать глазами, текстовый редактор с этим отлично справляется либо можно просто отнять/прибавить разницу в длине между старым и новым адресом.
Путь через «svnadmin setrevprop» также возможен, но, на мой вгляд, требует больше усилий и занимает больше времени. При таком подходе все равно нужно:
-найти в дампе все проблемные ревизии, где встречаются ссылки на внешний репозиторий
-каждое свойство, которое нужно поменять, скопировать в файл
-поправить ссылку в файле
-применить «svnadmin setrevprop» для каждого свойства
При предложенном мной подходе все изменения делаются по ходу просмотра файла дампа. Количество байт не нужно считать глазами, текстовый редактор с этим отлично справляется либо можно просто отнять/прибавить разницу в длине между старым и новым адресом.
Хм, интересно, как себя поведет svn, если задать все svn:externals для trunk, а потом сделать branch (под рукой нет, на чем проверить).
Ссылки на конкретные ревизии во внешнем репозитории — очень хорошо, о проблеме задумывался, но не знал, что так можно делать.
Немного печально, что svn как-то не очень развивавется по моим субъективным впечатлениям (может это просто проходит мимо меня? И почему тогда все массово переходят на альтернативные системы контроля версий?). Недостатки то реально есть, а переходить на что-то другое не вижу смысла, т. к. слишком много кода, используемого мной хранится именно в SVN репозиториях.
Спасибо за статью, познавательно.
Ссылки на конкретные ревизии во внешнем репозитории — очень хорошо, о проблеме задумывался, но не знал, что так можно делать.
Немного печально, что svn как-то не очень развивавется по моим субъективным впечатлениям (может это просто проходит мимо меня? И почему тогда все массово переходят на альтернативные системы контроля версий?). Недостатки то реально есть, а переходить на что-то другое не вижу смысла, т. к. слишком много кода, используемого мной хранится именно в SVN репозиториях.
Спасибо за статью, познавательно.
В branch получится пустая папка со свойствами svn:externals. По опыту могу сказать, что внешние включения надо использовать в меру и явно осознавая, что за этим последует.
В версии 1.6.17 (на которой находится мой проект) происходит так: создаешь бранч, делаешь апдейт бранча — и в рабочей копии появляются директории и файлы, подгруженные из svn:externals. То есть, все ок вполне — в рабочей копии branch получается тот же контент, что и в trunk (со всеми externals либами).
Но что в trunk, что в branch не видно эти включения через svn list или repo browser. Чтобы не теряться, в статье дан отличный совет — использовать свойства только для корневой папки.
Но что в trunk, что в branch не видно эти включения через svn list или repo browser. Чтобы не теряться, в статье дан отличный совет — использовать свойства только для корневой папки.
UFO just landed and posted this here
Субрепозиторий — это полностью репозиторий со всеми плюшками, а вот достать из меркуриала пределенную директорию, не таща за собой весь репозиторий, довольно проблематично(в силу организации самого репозитория в меркуриал). В этом свн выигрывает.
Внешние репозитории поддерживаются, но надо было плясать с бубном и ставить дополнительные модули. Когда решал данный вопрос, наткнулся на модуль(кажется форест), но завести его нормально не удалось. Кстати, сейчас свн поддерживается из коробки или все еще через плагины?
Впрочем проблемы в равной степени возникают и при попытке интегрировать между собой что-то в обратную сторону, т.е. забирать чт-то из репозитория меркуриал в свн.
Внешние репозитории поддерживаются, но надо было плясать с бубном и ставить дополнительные модули. Когда решал данный вопрос, наткнулся на модуль(кажется форест), но завести его нормально не удалось. Кстати, сейчас свн поддерживается из коробки или все еще через плагины?
Впрочем проблемы в равной степени возникают и при попытке интегрировать между собой что-то в обратную сторону, т.е. забирать чт-то из репозитория меркуриал в свн.
UFO just landed and posted this here
Возможно я неясно выразился, вопрс касался поддержки репозиториев других систем контроля версий. Про то, что субрепозитории поддерживаются из коробки я знал и так(а это значит что и внешние репозитории меркуриал).
По поводу выташить, я предпочитаю сам контролировать, что, куда и в каком объеме тащить :).
По поводу выташить, я предпочитаю сам контролировать, что, куда и в каком объеме тащить :).
Вот сейчас бьюсь над одной задачей в mercurial, которую довольно просто решал в subversion через externals. Есть внешний проект в репозитории, для которого я разрабатываю модуль и удаляю существующие в нём модули, плюс конфиги. В svn я помещал корень проекта в свой репозиторий и из него ссылался на подкаталоги внешнего проекта: мой модуль и мои конфиги работали с моим репозиторием, а по необходимости обновлял внешние каталоги. Как разрулить эту ситуацию в mercurial пока не представляю.
Мы использовали externals для интеграции модулей, разработанных сторонними разработчиками. В принципе получилось неплохо — у разработчиков были отдельные директории в общем репозитории. Те каталоги в основном дереве проекта, в которых должны были находиться эти модули были привязаны через externals к тем местам, куда разработчики выкладывали свои сборки (сборка их модулей не включалась в основную сборку). Кроме того, был еще один проект — тестовая система, позволяющая тестировать эти модули по отдельности. Она тоже была привязана через externals к модулям.
Правда, у externals есть еще один недостаток — не видно, какие папки используют externals, а какие — нет. Корме того, практика показала, что люди, не очень хорошо разбирающиеся в SVN, вообще не понимают, что такое externals, что иногда затрудняет работу.
Правда, у externals есть еще один недостаток — не видно, какие папки используют externals, а какие — нет. Корме того, практика показала, что люди, не очень хорошо разбирающиеся в SVN, вообще не понимают, что такое externals, что иногда затрудняет работу.
iText –r 247 itext.svn.sourceforge.net/svnroot/itext/trunk
Ничего не слышали про теги?
Вот посмотрите: itext.svn.sourceforge.net/svnroot/itext/tags/
>Мы изначально работали без внешних зависимостей, затем при декомпозиции проектов по нескольким репозиториям начали активно использовать svn:externals, однако со временем поняли, что недостатки перевешивают достоинства.
А каковы, с Вашей точки зрения, преимущества такой декомпозиции?
Если все хранить в одном репозитории в виде
-проект1
--trunk
--tags
--branches
-проект2
--trunk
--tags
--branches
-проект3
--trunk
--tags
--branches
и т.д., то преимущества таковы:
-Простота администрирования. Новый проект — это просто новая папка. Доступ пользователей описан в одном файле. Полный backup делается одним махом.
-Не нужно делать «externals». Можно попросту копировать в проект1 и проект3 нужные подпапки из нужных tags проекта2. Это аналог «нужно ссылаться на конкретную ревизию во внешнем репозитории»
Смысл разделять на несколько репозиториев?
А каковы, с Вашей точки зрения, преимущества такой декомпозиции?
Если все хранить в одном репозитории в виде
-проект1
--trunk
--tags
--branches
-проект2
--trunk
--tags
--branches
-проект3
--trunk
--tags
--branches
и т.д., то преимущества таковы:
-Простота администрирования. Новый проект — это просто новая папка. Доступ пользователей описан в одном файле. Полный backup делается одним махом.
-Не нужно делать «externals». Можно попросту копировать в проект1 и проект3 нужные подпапки из нужных tags проекта2. Это аналог «нужно ссылаться на конкретную ревизию во внешнем репозитории»
Смысл разделять на несколько репозиториев?
Преимущества декомпозиции:
— Если хранить все в одном репозитории, то получаются неудобства с нумерацией версий конкретных проектов (если завязывать нумерацию версий на номер ревизии). Например:
Работаем только над «проект1», сделали 300 коммитов, выпустили версию «проект1» 1.0.300
Затем переключаемся на «проект2», после 400 коммитов выпускаем версию «проект2» 1.0.600 (уже не совсем верно)
Возвращаемся к «проект1», делаем 1 коммит (небольшой фикс) и выпускаем версию — получается номер 1.0.601 (совсем некорректно)
— На начальном этапе это не заметно, но со временем размер репозитория сильно увеличивается. В истории накапливается куча ненужного. Например, представим ситуацию, когда какой-то проект больше ну совершенно не нужен — можно его удалить. Простое удаление из репозитория не уменьшит общий размер, ибо вся история останется.
Размер репозитория до поры-до времени будет не критичен, однако когда он вырастает до нескольких Гб — готовьтесь, что как только потребуется осуществлять какие-то действия с самим репозиторием — перенос на новый сервер, какую-то обработку дампа, миграцию в другую VCS — столкнетесь с проблемами.
— Декомпозиция дает большую гибкость в управлении репозиториями
Частичное повторение предыдущего пункта. Если захотите что-то сделать с репозиторием — выкинуть какую-то ненужную часть истории, сделать бэкап только одного проекта, перейти на Git — с декомпозированными репозиториями будет проще.
К слову, при декомпозиции никто не мешает также использовать копирование вместо externals, так что Ваше второе преимущество не совсем преимущество.
/////
Вообще, как показывает практика, и в других областях декомпозиция в большинстве случаев лучше. Ибо, обычно, делает вещи проще, например:
— Вся эволюция императивных языков программирования направлена на упрощение разработки и, соответственно, кода. И декомпозиция — главный инструмент для этого. Сейчас мы пришли к тому, что грамотно спроектированный проект:
1) Разделен на модули/компоненты, каждый из которых решает конкретную задачу;
2) Каждый компонент разделен на классы, каждый из которых в соответствии с хорошими практиками ООП решает 1 задачу;
3) Каждый класс разделен на методы, каждый из которых в идеале решает 1 задачу;
4) В каждом методе используются переменные и, в идеале, каждая переменная должна использоваться только для одной цели.
— Управление требованиями к проекту. Как проще — когда все требования по проекту в куче в одном документе или же аккуратно разнесены по разным задачам в трекере? Практика показывает, что второе.
— Если хранить все в одном репозитории, то получаются неудобства с нумерацией версий конкретных проектов (если завязывать нумерацию версий на номер ревизии). Например:
Работаем только над «проект1», сделали 300 коммитов, выпустили версию «проект1» 1.0.300
Затем переключаемся на «проект2», после 400 коммитов выпускаем версию «проект2» 1.0.600 (уже не совсем верно)
Возвращаемся к «проект1», делаем 1 коммит (небольшой фикс) и выпускаем версию — получается номер 1.0.601 (совсем некорректно)
— На начальном этапе это не заметно, но со временем размер репозитория сильно увеличивается. В истории накапливается куча ненужного. Например, представим ситуацию, когда какой-то проект больше ну совершенно не нужен — можно его удалить. Простое удаление из репозитория не уменьшит общий размер, ибо вся история останется.
Размер репозитория до поры-до времени будет не критичен, однако когда он вырастает до нескольких Гб — готовьтесь, что как только потребуется осуществлять какие-то действия с самим репозиторием — перенос на новый сервер, какую-то обработку дампа, миграцию в другую VCS — столкнетесь с проблемами.
— Декомпозиция дает большую гибкость в управлении репозиториями
Частичное повторение предыдущего пункта. Если захотите что-то сделать с репозиторием — выкинуть какую-то ненужную часть истории, сделать бэкап только одного проекта, перейти на Git — с декомпозированными репозиториями будет проще.
К слову, при декомпозиции никто не мешает также использовать копирование вместо externals, так что Ваше второе преимущество не совсем преимущество.
/////
Вообще, как показывает практика, и в других областях декомпозиция в большинстве случаев лучше. Ибо, обычно, делает вещи проще, например:
— Вся эволюция императивных языков программирования направлена на упрощение разработки и, соответственно, кода. И декомпозиция — главный инструмент для этого. Сейчас мы пришли к тому, что грамотно спроектированный проект:
1) Разделен на модули/компоненты, каждый из которых решает конкретную задачу;
2) Каждый компонент разделен на классы, каждый из которых в соответствии с хорошими практиками ООП решает 1 задачу;
3) Каждый класс разделен на методы, каждый из которых в идеале решает 1 задачу;
4) В каждом методе используются переменные и, в идеале, каждая переменная должна использоваться только для одной цели.
— Управление требованиями к проекту. Как проще — когда все требования по проекту в куче в одном документе или же аккуратно разнесены по разным задачам в трекере? Практика показывает, что второе.
>Если завязывать нумерацию версий на номер ревизии
Если завязывать, тогда да. Но, к примеру, у нас не завязано. Вы пишете: «перейти на Git — с декомпозированными репозиториями будет проще». А в git нет номера ревизии…
>На начальном этапе это не заметно, но со временем размер репозитория сильно увеличивается.
Ну, если проекты занимают десятки гигабайт, тогда, конечно, этот фактор имеет значение. Но не является ли такой размер признаком хранения в VCS того, чего там хранить не надо? :)
>миграцию в другую VCS — столкнетесь с проблемами
Хотелось бы конкретики. Если мигрировать на что-то типа mercurial/git, то мигрировать будет не весь репозиторий, а только какой-то проект или даже его часть.
>К слову, при декомпозиции никто не мешает также использовать копирование вместо externals
При этом, однако, информация дублируется, места на диске будет уходить больше. Ну и кликнуть пару раз в одном репозитории гораздо проще, чем перебрасывать файлы между отдельными репозиториями.
>Вообще, как показывает практика, и в других областях декомпозиция в большинстве случаев лучше.
С этим согласен. Однако тут мы имеем дело с декомпозицией двух видов — так сказать, логической и физической. Логически проекты и так можно хорошо декомпозировать, даже если они в одном репозитории. Вынос проекта в другой репозиторий с точки зрения заказчика/аналитика/проектировщика/разработчика ничего нового не привносит, просто меняется url проекта.
Если завязывать, тогда да. Но, к примеру, у нас не завязано. Вы пишете: «перейти на Git — с декомпозированными репозиториями будет проще». А в git нет номера ревизии…
>На начальном этапе это не заметно, но со временем размер репозитория сильно увеличивается.
Ну, если проекты занимают десятки гигабайт, тогда, конечно, этот фактор имеет значение. Но не является ли такой размер признаком хранения в VCS того, чего там хранить не надо? :)
>миграцию в другую VCS — столкнетесь с проблемами
Хотелось бы конкретики. Если мигрировать на что-то типа mercurial/git, то мигрировать будет не весь репозиторий, а только какой-то проект или даже его часть.
>К слову, при декомпозиции никто не мешает также использовать копирование вместо externals
При этом, однако, информация дублируется, места на диске будет уходить больше. Ну и кликнуть пару раз в одном репозитории гораздо проще, чем перебрасывать файлы между отдельными репозиториями.
>Вообще, как показывает практика, и в других областях декомпозиция в большинстве случаев лучше.
С этим согласен. Однако тут мы имеем дело с декомпозицией двух видов — так сказать, логической и физической. Логически проекты и так можно хорошо декомпозировать, даже если они в одном репозитории. Вынос проекта в другой репозиторий с точки зрения заказчика/аналитика/проектировщика/разработчика ничего нового не привносит, просто меняется url проекта.
Не мог пройти мимо посылки, что ООП средство декомпозиции. Наоборот, ООП средство композиции, собирающее все связанные данные и методы/сигналы работы с ними под одну «крышу», усиливающее, а не ослабляющее внутренние связи. Хорошие практики ООП заключаются в том, чтобы вынести то, что можно вынести без нарушения внутренней целостности, но куда главнее не забыть внести то, что нужно внести, без введения излишних внешних связей. А если следовать вашим рассуждением, то идеалом проекта будет его реализация на процедурных языках, а то и на простейшем «ассемблере», поддерживающем из структур управления лишь условный переход.
Напротив, эволюция языков императивного программирования основана на всё более многоуровневой композиции (составлении) новых элементов из существовавших до этого (как правило, со скрытием и недоступностью для разработчика деталей реализации нового элемента). Сначала были метки и условные переходы, а потом появились циклы. Сначала были процедуры/функции, а потом появились объекты и методы.
Необходимость декомпозиции появляется когда мы вольно или невольно, случайно или закономерно пришли к излишней композиции (слишком много слабосвязанных методов/переменных в классе, слишком много слабосвязанных каталогов/файлов в проекте). Равно как и необходимость коспозиции появляется в случае слишком слабой «физической» связи элементов, явно «логически» связанных.
У оптыного разработчика, имхо, композиция появляется намного чаще декомпозиции при разработке снизу вверх, а декомпозиция чаще композиции при разработке сверху вниз. Идёт разработка релиза на ЯП или формирование структуры каталогов/репозиториев — не важно.
Если разработчик достаточно опытен
Напротив, эволюция языков императивного программирования основана на всё более многоуровневой композиции (составлении) новых элементов из существовавших до этого (как правило, со скрытием и недоступностью для разработчика деталей реализации нового элемента). Сначала были метки и условные переходы, а потом появились циклы. Сначала были процедуры/функции, а потом появились объекты и методы.
Необходимость декомпозиции появляется когда мы вольно или невольно, случайно или закономерно пришли к излишней композиции (слишком много слабосвязанных методов/переменных в классе, слишком много слабосвязанных каталогов/файлов в проекте). Равно как и необходимость коспозиции появляется в случае слишком слабой «физической» связи элементов, явно «логически» связанных.
У оптыного разработчика, имхо, композиция появляется намного чаще декомпозиции при разработке снизу вверх, а декомпозиция чаще композиции при разработке сверху вниз. Идёт разработка релиза на ЯП или формирование структуры каталогов/репозиториев — не важно.
Если разработчик достаточно опытен
Ваш посыл (ООП — средство композиции) не менее спорен. :-)
С моей точки зрения, программирование (как процесс создания программы) — это композиция. А разбиение задачи на составные части (максимально независимые друг от друга) и реализация объектов для решения мелких задач — это декомпозиция.
То есть создание класса, как по мне, это декомпозиция, так как часть функционала и данных выделяется из общего пространства имен или общих данных в отдельную сущность.
С моей точки зрения, программирование (как процесс создания программы) — это композиция. А разбиение задачи на составные части (максимально независимые друг от друга) и реализация объектов для решения мелких задач — это декомпозиция.
То есть создание класса, как по мне, это декомпозиция, так как часть функционала и данных выделяется из общего пространства имен или общих данных в отдельную сущность.
для удобного испольхования чужого кода мы сделали две ветки trunk и upstream. заливаем в upstream копию из чужого репозитория, комитим, копируем в trunk, в trunk делаем наши правки, иногда обновляем upstream и делаем слияние в trunk
Если внешний репозиторий тоже под SVN, то самым приятным вариантом мне кажется хранение копии исходников и периодический честный мерж из внешнего репозитория. Я, например, в самом репозитории храню файл merge.sh такого вида:
Когда мне хочется вмержить новый диапазон версий из внешнего репозитория, я вижу диапазон версий, который уже вмержен. Вместе с коммитом результатов мержа в репозиторий попадает файл merge.sh с новым диапазоном версий. Т.е. фактически получаем все преимущества svn:externals, избегая всех его недостатков.
REV1=4351 REV2=4375 EXT_REPO_PATH=svn://... DIR=ext_lib_dir USER=username mv merge.log merge.log.bak svn merge -r $REV1:$REV2 $EXT_REPO_PATH DIR --username $USER >merge.log
Когда мне хочется вмержить новый диапазон версий из внешнего репозитория, я вижу диапазон версий, который уже вмержен. Вместе с коммитом результатов мержа в репозиторий попадает файл merge.sh с новым диапазоном версий. Т.е. фактически получаем все преимущества svn:externals, избегая всех его недостатков.
Sign up to leave a comment.
Практические аспекты использования svn:externals