Как вы организуете свой репозиторий для контроля версий?

Во-первых, я знаю об этом: Как Не могли бы вы организовать репозиторий Subversion для собственных программных проектов? Затем, собственно, вопрос: моя команда реструктурирует наш репозиторий, и я ищу подсказки, как его организовать. (В данном случае SVN). Вот что мы придумали. У нас есть один репозиторий, несколько проектов и несколько перекрестных ссылок svn: externals

\commonTools /*tools used in all projects. Referenced in each project with svn:externals*/
   \NUnit.v2.4.8
   \NCover.v.1.5.8
   \<other similar tools>
\commonFiles /*settings strong name keys etc.*/
   \ReSharper.settings
   \VisualStudio.settings
\trash /*each member of the team has trash for samples, experiments etc*/
   \user1
   \user2
\projects
   \Solution1 /*Single actual project (Visual Studio Solution)*/
      \trunk
         \src
             \Project1 /*Each sub-project resulting in single .dll or .exe*/
             \Project2
         \lib
         \tools
         \tests
         \Solution1.sln
      \tags
      \branches
   \Solution2
      \trunk
         \src
             \Project3 /*Each sub-project resulting in single .dll or .exe*/
             \Project1 /*Project1 from Solution1 references with svn:externals*/
         \lib
         \tools
         \tests
         \Solution2.sln
      \tags
      \branches

Чтобы очистить словарный запас: Решение означает один продукт, Project - это проект Visual Studio (в результате получается один файл .dll или один .exe)

Вот так планируем выкладывать репозиторий. Основная проблема в том, что у нас есть несколько решений, но мы хотим разделять проекты между решениями. Мы подумали, что на самом деле нет смысла переносить эти общие проекты в их собственные решения, и вместо этого мы решили использовать svn: externals для совместного использования проектов между решениями. Мы также хотим сохранить общий набор инструментов и сторонних библиотек в одном месте в репозитории, и они будут ссылаться на них в каждом Решении с помощью svn: externals.

Что вы думаете об этом макете? Особенно об использовании svn: externals. Это не идеальное решение, но, учитывая все плюсы и минусы, это лучшее, что мы могли придумать. Как бы ВЫ это сделали?


person Krzysztof Kozmic    schedule 21.10.2008    source источник
comment
Вы уверены, что имеете в виду трэш? А точнее хлам?   -  person ssc    schedule 08.02.2014


Ответы (8)


Если вы будете следовать моим рекомендациям, приведенным ниже (я делал это годами), вы сможете:

- поместите каждый проект в любом месте системы управления версиями, пока вы сохраняете структуру из корневого каталога проекта вниз

- строить каждый проект в любом месте на любой машине с минимальным риском и минимальной подготовкой

- строить каждый проект полностью автономным, если у вас есть доступ к его двоичным зависимостям (локальные каталоги "библиотека" и "выход")

- строить и работать с любой комбинацией проектов, поскольку они независимы

- строить и работать с несколькими копиями / версиями одного проекта, поскольку они независимы

- избегайте загромождения репозитория системы управления версиями сгенерированными файлами или библиотеками.

Рекомендую (вот говядина):

  1. Определите каждый проект для создания одного основного конечного результата, например .DLL, .EXE или .JAR (по умолчанию в Visual Studio).

  2. Структурируйте каждый проект как дерево каталогов с одним корнем.

  3. Создайте сценарий автоматической сборки для каждого проекта в его корневом каталоге, который будет строить его с нуля, без каких-либо зависимостей от IDE (но не препятствуйте его созданию в IDE, если это возможно).

  4. Рассмотрим nAnt для проектов .NET в Windows или что-то подобное в зависимости от вашей ОС, целевой платформы и т. Д.

  5. Сделайте так, чтобы каждый сценарий сборки проекта ссылался на свои внешние (сторонние) зависимости из единого локального общего каталога «библиотеки», причем каждый такой двоичный файл ПОЛНОСТЬЮ идентифицировался по версии: %DirLibraryRoot%\ComponentA-1.2.3.4.dll, %DirLibraryRoot%\ComponentB-5.6.7.8.dll.

  6. Сделайте так, чтобы каждый сценарий сборки проекта публиковал основной результат в единственном локальном общем «выходном» каталоге: %DirOutputRoot%\ProjectA-9.10.11.12.dll, %DirOutputRoot%\ProjectB-13.14.15.16.exe.

  7. Сделайте так, чтобы каждый сценарий сборки проекта ссылался на свои зависимости через настраиваемые абсолютные пути с полной версией (см. Выше) в каталогах «library» и «output», И НЕТ ГДЕ ДРУГОЕ.

  8. НИКОГДА не позволяйте проекту напрямую ссылаться на другой проект или какое-либо его содержимое - разрешайте ссылки только на основные результаты в «выходном» каталоге (см. Выше).

  9. Сделайте так, чтобы каждый скрипт сборки проекта ссылался на необходимые инструменты сборки по настраиваемому абсолютному пути с полной версией: %DirToolRoot%\ToolA\1.2.3.4, %DirToolRoot%\ToolB\5.6.7.8.

  10. Сделайте все ссылки на исходный контент сценария сборки проекта по абсолютному пути относительно корневого каталога проекта: ${project.base.dir}/src, ${project.base.dir}/tst (синтаксис зависит от инструмента сборки).

  11. ВСЕГДА требуется, чтобы сценарий сборки проекта ссылался на КАЖДЫЙ файл или каталог через абсолютный настраиваемый путь (с корнем в каталоге, указанном настраиваемой переменной): ${project.base.dir}/some/dirs или ${env.Variable}/other/dir.

  12. НИКОГДА не позволяйте сценарию сборки проекта ссылаться на НИЧЕГО с относительным путем, например .\some\dirs\here или ..\some\more\dirs, ВСЕГДА используйте абсолютные пути.

  13. НИКОГДА не позволяйте сценарию сборки проекта ссылаться на НИЧЕГО, используя абсолютный путь, не имеющий настраиваемого корневого каталога, например C:\some\dirs\here или \\server\share\more\stuff\there.

  14. Для каждого настраиваемого корневого каталога, на который ссылается сценарий сборки проекта, определите переменную среды, которая будет использоваться для этих ссылок.

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

  16. На каждой машине создайте сценарий оболочки, который определяет необходимые переменные среды, специфичные для ЭТОЙ машины (и, возможно, специфичные для этого пользователя, если это необходимо).

  17. НЕ помещайте машинно-зависимый сценарий оболочки конфигурации в систему управления версиями; вместо этого для каждого проекта зафиксируйте копию сценария в корневом каталоге проекта в качестве шаблона.

  18. ТРЕБУЕТСЯ каждый сценарий сборки проекта для проверки каждой из его переменных среды и прерывание с выводом значимого сообщения, если они не определены.

  19. ТРЕБУЕТСЯ каждый сценарий сборки проекта для проверки каждого из его зависимых исполняемых файлов инструмента сборки, файлов внешних библиотек и зависимых файлов результатов проекта и прекращает работу с выдачей значимого сообщения, если эти файлы не существуют.

  20. УСТОЙЧИВАЙТЕСЬ от соблазна передать ЛЮБЫЕ сгенерированные файлы в систему контроля версий - без результатов проекта, без сгенерированного источника, без сгенерированной документации и т. Д.

  21. Если вы используете IDE, создайте любые файлы управления проектом, которые вы можете, и не фиксируйте их в системе управления версиями (включая файлы проекта Visual Studio).

  22. Установите сервер с официальной копией всех внешних библиотек и инструментов, которые будут скопированы / установлены на рабочих станциях разработчиков и сборочных машинах. Создайте резервную копию вместе с репозиторием системы управления версиями.

  23. Установите сервер непрерывной интеграции (машину сборки) без каких-либо инструментов разработки.

  24. Рассмотрим инструмент для управления внешними библиотеками и продуктами, например Ivy (используется с Ant).

  25. НЕ используйте Maven - это сначала сделает вас счастливыми, а в конечном итоге заставит плакать.

Обратите внимание, что ничто из этого не является специфическим для Subversion, и большинство из них является общим для проектов, ориентированных на любую ОС, оборудование, платформу, язык и т. Д. Я действительно использовал немного синтаксиса, специфичного для ОС и инструмента, но только для иллюстрации - -Я надеюсь, что вы переведете на вашу ОС или выбранный вами инструмент.

Дополнительное примечание относительно решений Visual Studio: не помещайте их в систему контроля версий! При таком подходе они вам вообще не нужны или вы можете их сгенерировать (как файлы проекта Visual Studio). Однако я считаю, что лучше оставить файлы решений отдельным разработчикам, чтобы они создавали / использовали их по своему усмотрению (но не регистрировались в системе управления версиями). У меня есть Rob.sln файл на моей рабочей станции, из которого я ссылаюсь на мои текущие проекты. Поскольку все мои проекты автономны, я могу добавлять / удалять проекты по своему желанию (что означает отсутствие ссылок на зависимости на основе проектов).

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

Когда вы реализуете непрерывную интеграцию или даже если вы просто хотите автоматизировать процесс выпуска, создайте для этого сценарий. Создайте единый сценарий оболочки, который: принимает параметры имени проекта (как указано в репозитории) и имени тега, создает временный каталог в настраиваемом корневом каталоге, проверяет источник для данного имени проекта и имени тега (путем создания соответствующий URL-адрес в случае Subversion) к этому временному каталогу, выполняет чистую сборку, которая запускает тесты и упаковывает результат. Этот сценарий оболочки должен работать с любым проектом и должен быть зарегистрирован в системе управления версиями как часть вашего проекта «инструментов сборки». Ваш сервер непрерывной интеграции может использовать этот сценарий в качестве основы для создания проектов или даже предоставить его (но вы все равно можете захотеть свой собственный).

@VonC: вы НЕ хотите постоянно работать с «ant.jar», а не с «ant-a.b.c.d.jar» после того, как вы обожжетесь, когда ваш сценарий сборки сломается, потому что вы неосознанно запустили его с несовместимой версией Ant. Это особенно характерно для Ant 1.6.5 и 1.7.0. Обобщая, вы ВСЕГДА хотите знать, какая конкретная версия КАЖДОГО компонента используется, включая вашу платформу (Java A.B.C.D) и ваш инструмент сборки (Ant E.F.G.H). В противном случае вы в конечном итоге столкнетесь с ошибкой, и ваша первая БОЛЬШАЯ проблема будет заключаться в том, чтобы отследить, какие версии ваших различных компонентов задействованы. Просто лучше решить эту проблему заранее.

person Rob Williams    schedule 20.11.2008
comment
Так много моментов для критики ... достаточно сказать, что это не универсальный рецепт! Пункты 5 и 6, в частности, неверны, когда проект большой и важно количество третьих лиц: вы хотите постоянно работать с ant.jar, а не с ant1.5.4.jar или продуктом myProduct. .exe, а не 1.3.exe - person VonC; 20.11.2008
comment
Тем не менее, +1 за многие другие ваши замечания, которые являются действительными и хорошо говорят о вашем обширном опыте по данной теме. - person VonC; 20.11.2008
comment
Я хотел бы услышать вашу критику и отреагировать на нее - каждая точка зрения основана на решении неудачных опытов с крупными проектами. Например, решение вопроса о том, какие версии представлены файлами Xxx.jar и Yyy.exe, особенно когда имеется буквально дюжина копий, на которые ссылаются. - person Rob Williams; 20.11.2008
comment
@VonC: Я подозреваю, что ваше желание сослаться на myProduct.exe может быть связано с разработкой на основе последнего снимка, например, представленного Maven. В этом случае я был бы склонен согласиться, и использование соглашения, аналогичного Maven, может быть наиболее подходящим. - person Rob Williams; 20.11.2008
comment
@Rob - Не могли бы вы подробнее рассказать о своей теме «внешнего антипаттерна»? Я поднял это как вопрос здесь: stackoverflow.com / questions / 338824 / - person Ken; 04.12.2008
comment
№12 противоречит здравому смыслу. Это означает, что у всех должна быть одна и та же файловая система, и все файлы должны располагаться на одном диске. Многие виртуальные компьютеры позволяют создавать диски, подключенные к данным, и это может испортить ситуацию. И мне просто интересно, что случилось бы с моей системой в последнее время, когда некий общий ресурс сетевого слова должен был быть отображен на M: но по какой-то причине моя машина не позволяла мне сопоставить это, поэтому мне пришлось использовать N: вместо этого ... - person Makis; 26.06.2009
comment
@Makis: Вы были бы правы, ЕСЛИ № 12 не был сбалансирован № 13. Каждая ссылка на файл или каталог в каждом проекте должна выполняться через абсолютный путь, который начинается с настраиваемой переменной корневого каталога, например $ {basedir} /sub/dir/file.txt в Ant. - person Rob Williams; 07.07.2009
comment
Почему вы предпочитаете Ant вместо Maven2? Мой опыт совершенно противоположен. - person Petr Macek; 04.01.2010
comment
Здесь есть хороший контент, и люди должны знать обо всех возможностях, которые у них есть. Однако я не согласен с тем, что это универсальное решение. - person Tim; 16.08.2010
comment
Это ужасное решение, поскольку оно подразумевает, что каждый раз, когда вы хотите строить или работать, вы должны быть на связи. Мне очень жаль, но двоичные файлы svn-external намного шустрее, так как рабочая копия содержит все, что вам нужно, включая ваши инструменты (nant / msbuild / ncover). Хороший звонок о NMaven, хотя - person Florian Doyon; 02.12.2010
comment
Спасибо за этот великий пост! Один вопрос по поводу №8: что делать с заголовочными (.h) файлами в C ++? Вы бы скопировали их в общий каталог? А как насчет импортных и статических библиотек? - person Bojan; 12.03.2011
comment
Как и большинство комментаторов, я здесь не со всем согласен. Что касается пункта 8, не повредит ли это отладке? Вы не сможете выполнять отладку из одного проекта в другой, что серьезно затрудняет вам выполнение отладки интеграции. И вы говорите не помещать файлы .sln в систему контроля версий; как насчет того, когда один проект зависит от другого? Как узнать, что построить в первую очередь? Самостоятельное управление этим в сценарии сборки кажется лишней дополнительной работой. Некоторые из ваших стратегий кажутся слишком идеалистичными и не подходят для большинства реальных проектов любого реального размера. - person deadlydog; 02.02.2013
comment
Не возвращать файлы решений или файлы проекта? Как вы управляете действиями сборки? (например, встроенные ресурсы)? Или скопировал / не скопировал в выходной каталог? Как вы решаете, должен ли файл быть включен или исключен как часть вашего проекта? - person Rocklan; 08.04.2015
comment
Я полностью согласен с тем, что это надежный, последовательный и полезный подход. Всего несколько заметок от кого-то, кто имеет опыт работы с UNIX. Заголовки - это файлы OUTPUT, поэтому они сохраняются в каталоге вывода. Из-за проверки зависимостей новые сборки завершатся ошибкой, пока вы не соберете необходимые компоненты (в правильных версиях). Может быть рекомендован главный сценарий сборки, который выполняет проверку и сборку; но это должно быть вне проекта или в метапроекте. - person William Entriken; 02.12.2015
comment
У меня тот же вопрос, что и у @deadlydog. Не могли бы вы подробнее рассказать об этом? Как вы справляетесь с отладкой, если проекты не ссылаются на проекты? Конечно, вы можете прикрепить исходный код к двоичным файлам и выполнить код (думая о Java + Eclipse), но разве каждое изменение одного из проектов не требует компиляции + dist + перезапуска? - person NickL; 05.01.2018

Я считаю, что в Pragmatic Version Control с использованием Subversion есть все вам нужно организовать свой репозиторий.

person Fabio Gomes    schedule 21.10.2008
comment
@bal Пожалуйста, не используйте службы сокращения URL-адресов. намного лучше сказать Сейчас во 2-м издании: Прагматичный контроль версий с помощью Subversion - person meagar; 25.01.2011

Мы настроили наши так, чтобы они почти точно соответствовали тому, что вы опубликовали. Используем общую форму:

\Project1
   \Development (for active dev - what you've called "Trunk", containing everything about a project)
   \Branches (For older, still-evolving supported branches of the code)
       \Version1
       \Version1.1
       \Version2
   \Documentation (For any accompanying documents that aren't version-specific

Хотя я полагаю, что он не такой полный, как ваш пример, он хорошо сработал для нас и позволяет нам хранить вещи отдельно. Мне также нравится идея, что у каждого пользователя есть папка «Thrash» - в настоящее время проекты такого типа не попадают в систему управления версиями, и я всегда чувствовал, что должны.

person SqlRyan    schedule 21.10.2008
comment
Я удивлен, что у вас есть отдельный каталог для документов, которые не меняются между версиями ... Я никогда не имел удовольствия работать над таким продуктом! :) - person ARKBAN; 20.11.2008

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

Ну, по крайней мере, я привык к подходу «один проект на репозиторий». Мне кажется, что структура вашего репозитория слишком сложна.

А сколько проектов вы планируете поместить в один большой репозиторий? 2? 3? 10? 100?

А что вы делаете, когда отменяете разработку одного проекта? Просто удалите его из дерева репозиториев, и в будущем его будет сложно найти. Или оставить его валяться навсегда? Или когда вы хотите вообще переместить один проект на другой сервер?

А как насчет беспорядка со всеми этими номерами версий? Номера версий одного проекта выглядят как 2, 10, 11, а другого - как 1, 3, 4, 5, 6, 7, 8, 9, 12 ...

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

person Rene Saarsoo    schedule 21.10.2008
comment
1. Один репозиторий - это политика компании, это изменить нельзя. 2. У нас будет около десятка решений. 3. под номерами версий вы подразумеваете ревизии? Для нас это не проблема. - person Krzysztof Kozmic; 21.10.2008
comment
Хорошая структура проекта должна игнорировать остальную часть структуры репозитория, особенно в отношении одного или нескольких репозиториев. Пожалуйста, посмотрите мой подробный ответ. - person Rob Williams; 20.11.2008
comment
Обратите внимание, что наличие нескольких репозиториев во многих (большинстве?) Инструментов управления версиями может быть ОЧЕНЬ дорого, например, при реализации безопасности. - person Rob Williams; 20.11.2008

Я думаю, что основным недостатком предложенной структуры является то, что общие проекты будут версироваться только с первым решением, к которому они были добавлены (если svn: externals не выглядит более привлекательным, чем я могу себе представить). Например, когда вы создаете ветвь для первого выпуска Solution2, Project1 не будет разветвлен, поскольку он находится в Solution1. Если вам потребуется выполнить сборку из этой ветки позже (выпуск QFE), он будет использовать последнюю версию Project1, а не версию Project1 на момент создания ветки.

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

person C. Dragon 76    schedule 21.10.2008
comment
В какой-то мере вы правы. Но мы можем обновить ссылку, если захотим. И помещать общие проекты в их собственное Решение тоже не имеет большого смысла. Хотя я хотел бы найти лучшее решение, чем svn: externals повсюду. - person Krzysztof Kozmic; 21.10.2008
comment
Что вы подразумеваете под обновлением ссылки, если мы хотим? Я не понимаю, как вы могли бы разветвлять Project1 (что кажется желательным всякий раз, когда вы разветвляете Solution2) без разветвления Solution1. - person C. Dragon 76; 22.10.2008
comment
Пожалуйста, посмотрите мой подробный ответ, в частности, чтобы НЕ помещать решения Visual Studio в систему контроля версий. - person Rob Williams; 20.11.2008

Чтобы добавить к проблеме относительного пути:

Я не уверен, что это проблема:
Просто проверьте Solution1 / trunk в каталоге с именем «Solution1», то же самое для Solution2: цель «каталогов», фактически представляющих ветви, - не быть видимыми однажды импортированный в рабочую область. Следовательно, возможны относительные пути между «Solution1» (фактически «Solution1 / trunk») и «Solution2» (Solution2 / trunk).

person VonC    schedule 21.10.2008
comment
Это очень легко сломается, пожалуйста, посмотрите мой подробный ответ. - person Rob Williams; 20.11.2008

RE: относительный путь и проблема с общим файлом -

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

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

person Tim    schedule 21.10.2008
comment
Если проекты ссылаются на другие проекты, это создает кошмар обслуживания, потому что зависимости растут экспоненциально, а ссылки ОЧЕНЬ хрупкие. Пожалуйста, посмотрите мой подробный ответ. - person Rob Williams; 20.11.2008

У меня аналогичная планировка, но мой ствол, ветки, метки полностью вверху. Итак: / trunk / main, / trunk / utils, / branch / release / и т. Д.

Это оказалось очень удобно, когда мы хотели опробовать другие системы управления версиями, потому что многие инструменты перевода лучше всего работали с базовым макетом SVN из учебника.

person Community    schedule 21.10.2008