Как использовать Mercurial subrepos для общих компонентов и зависимостей?

Мы разрабатываем .NET Enterprise Software на C #. Мы стремимся улучшить нашу систему контроля версий. Я использовал Mercurial раньше и экспериментировал с его использованием в нашей компании. Тем не менее, поскольку мы разрабатываем корпоративные продукты, мы уделяем большое внимание повторно используемым компонентам или модулям. Я пытался использовать суб-репозитории Mercurial для управления компонентами и зависимостями, но у меня возникли некоторые трудности. Вот основные требования для контроля версий / управления зависимостями:

Reusable components Shared by source (for debugging) Have dependencies on 3rd party binaries and other reusable components Can be developed and commited to source control in the context of a consuming product Dependencies Products have dependencies on 3rd party binaries and other reusable components Dependencies have their own dependencies Developers should be notified of version conflicts in dependencies

Вот структура в Mercurial, которую я использовал:

A reusable component:
SHARED1_SLN-+-docs
            |
            +-libs----NLOG
            |
            +-misc----KEY
            |
            +-src-----SHARED1-+-proj1
            |                 +-proj2
            |
            +-tools---NANT
A second reusable component, consuming the first:
SHARED2_SLN-+-docs
            |
            +-libs--+-SHARED1-+-proj1
            |       |         +-proj2
            |       |
            |       +-NLOG
            |
            +-misc----KEY
            |
            +-src-----SHARED2-+-proj3
            |                 +-proj4
            |
            +-tools---NANT            
A product that consumes both components:
PROD_SLN----+-docs
            |
            +-libs--+-SHARED1-+-proj1
            |       |         +-proj2
            |       |
            |       +-SHARED2-+-proj3
            |       |         +-proj4
            |       |
            |       +-NLOG
            |
            +-misc----KEY
            |
            +-src-----prod----+-proj5
            |                 +-proj6
            |
            +-tools---NANT
Notes Repos are in CAPS All child repos are assumed to be subrepos 3rd party (binary) libs and internal (source) components are all subrepos located in the libs folder 3rd party libs are kept in individual mercurial repos so that consuming projects can reference particular versions of the libs (i.e. an old project may reference NLog v1.0, and a newer project may reference NLog v2.0). All Visual Studio .csproj files are at the 4th level (proj* folders) allowing for relative references to dependencies (i.e. ../../../libs/NLog/NLog.dll for all Visual Studio projects that reference NLog) All Visual Studio .sln files are at the 2nd level (src folders) so that they are not included when "sharing" a component into a consuming component or product Developers are free to organize their source files as they see fit, as long as the sources are children of proj* folder of the consuming Visual Studio project (i.e., there can be n children to the proj* folders, containing various sources/resources) If Bob is developing SHARED2 component and PROD1 product, it is perfectly legal for him to make changes the SHARED2 source (say sources belonging to proj3) within the PROD1_SLN repository and commit those changes. We don't mind if someone develops a library in the context of a consuming project. Internally developed components (SHARED1 and SHARED2) are generally included by source in consuming project (in Visual Studio adding a reference to a project rather than browsing to a dll reference). This allows for enhanced debugging (stepping into library code), allows Visual Studio to manage when it needs to rebuild projects (when dependencies are modified), and allows the modification of libraries when required (as described in the above note). Questions

If Bob is working on PROD1 and Alice is working on SHARED1, how can Bob know when Alice commits changes to SHARED1. Currently with Mercurial, Bob is forced to manually pull and update within each subrepo. If he pushes/pulls to the server from PROD_SLN repo, he never knows about updates to subrepos. This is described at Mercurial wiki. How can Bob be notified of updates to subrepos when he pulls the latest of PROD_SLN from the server? Ideally, he should be notified (preferable during the pull) and then have to manually decide which subrepos he wants to updated.

Assume SHARED1 references NLog v1.0 (commit/rev abc in mercurial) and SHARED2 references Nlog v2.0 (commit/rev xyz in mercurial). If Bob is absorbing these two components in PROD1, he should be be made aware of this discrepancy. While technically Visual Studio/.NET would allow 2 assemblies to reference different versions of dependencies, my structure does not allow this because the path to NLog is fixed for all .NET projects that depend on NLog. How can Bob know that two of his dependencies have version conflicts?

If Bob is setting up the repository structure for PROD1 and wants to include SHARED2, how can he know what dependencies are required for SHARED2? With my structure, he would have to manually clone (or browse on the server) the SHARED2_SLN repo and either look in the libs folder, or peak at the .hgsub file to determine what dependencies he needs to include. Ideally this would be automated. If I include SHARED2 in my product, SHARED1 and NLog are auto-magically included too, notifying me if there is version conflict with some other dependency (see question 2 above).

Bigger Questions

Is mercurial the correct solution?

Is there a better mercurial structure?

Is this a valid use for subrepos (i.e. Mercurial developers marked subrepos as a feature of last resort)?

Does it make sense to use mercurial for dependency management? We could use yet another tool for dependency management (maybe an internal NuGet feed?). While this would work well for 3rd party dependencies, it really would create a hassle for internally developed components (i.e. if they are actively developed, developers would have to constantly update the feed, we would have to serve them internally, and it would not allow components to be modified by a consuming project (Note 8 and Question 2).

Do you have better a solution for Enterprise .NET software projects?

References

Я прочитал несколько ТАК вопросов и нашелэтот быть полезным, нопринятый ответ предлагает использовать специальный инструмент для зависимостей. Хотя мне нравятся возможности такого инструмента, он не позволяет изменять зависимости и фиксировать их из потребляющего проекта (см. Более широкий вопрос 4).

Ответы на вопрос(2)

Ваш ответ на вопрос