还请注意,您引用的Wiki页面确实列出了一些与外壳存储库有关的特定问题: 编辑2-进行试验,涉及所有用户我们真正开始意识到的一个问题是,一旦多个用户开始进行提交,牵拉和推送(包括对子仓库的更改),我们就会遇到问题.对于我们来说,现在响应这些问题为时已晚.如果我们早点认识他们,我们本来可以更轻松,更简单地做出响应.因此,在这一点上,我认为我能提供的最佳建议是建议您在将布局刻在石头上之前先进行项目布局的试运行.我们离开了全面试用版,直到为时已晚,无法进行更改为止,即使这样,人们也只能在父存储库中进行更改,而不是在子存储库中进行更改-因此我们仍然看不到完整图片,直到为时已晚.换句话说,无论您考虑哪种布局,都需要在该布局中创建存储库结构,并需要很多人进行编辑.尝试在各种回购/子回购中放入足够的真实代码,以便人们可以进行真正的编辑,即使它们是一次性的.可能的结果:您可能会发现一切正常-在这种情况下,您将花费一些时间来确定性.另一方面,您可能比花时间试图确定结果要快得多地找出问题您的用户也会学到很多东西.We develop .NET Enterprise Software in C#. We are looking to improve our version control system. I have used mercurial before and have been experimenting using it at our company. However, since we develop enterprise products we have a big focus on reusable components or modules. I have been attempting to use mercurial's sub-repos to manage components and dependencies but am having some difficulties. Here are the basic requirements for source control/dependency management:Reusable componentsShared by source (for debugging)Have dependencies on 3rd party binaries and other reusable componentsCan be developed and commited to source control in the context of a consuming productDependenciesProducts have dependencies on 3rd party binaries and other reusable componentsDependencies have their own dependenciesDevelopers should be notified of version conflicts in dependenciesHere is the structure in mercurial that I have been using:A reusable component:SHARED1_SLN-+-docs | +-libs----NLOG | +-misc----KEY | +-src-----SHARED1-+-proj1 | +-proj2 | +-tools---NANTA second reusable component, consuming the first:SHARED2_SLN-+-docs | +-libs--+-SHARED1-+-proj1 | | +-proj2 | | | +-NLOG | +-misc----KEY | +-src-----SHARED2-+-proj3 | +-proj4 | +-tools---NANTA product that consumes both components:PROD_SLN----+-docs | +-libs--+-SHARED1-+-proj1 | | +-proj2 | | | +-SHARED2-+-proj3 | | +-proj4 | | | +-NLOG | +-misc----KEY | +-src-----prod----+-proj5 | +-proj6 | +-tools---NANTNotesRepos are in CAPSAll child repos are assumed to be subrepos3rd party (binary) libs and internal (source) components are all subrepos located in the libs folder3rd 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 productDevelopers 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).QuestionsIf 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 QuestionsIs 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?ReferencesI have read several SO questions and found this one to be helpful, but the accepted answer suggests using a dedicated tool for dependencies. While I like the features of such a tool it does not allowed for dependencies to be modified and committed from a consuming project (see Bigger Question 4). 解决方案 This may not be the answer you were looking for, but we have recent experience of novice Mercurial users using sub-repos, and I've been looking for an opportunity to pass on our experience...In summary, my advice based on experience is: however appealing Mercurial sub-repos may be, do not use them. Instead, find a way to lay out your directories side-by-side, and to adjust your builds to cope with that.However appealing it seems to be to tie together revisions in the sub-repo with revisions in the parent repo, it just doesn't work in practice.During all the preparation for the conversion, we received advice from multiple different sources that sub-repos were fragile and not well-implemented - but we went ahead anyway, as we wanted atomic commits between repo and sub-repo. The advice - or my understanding of it - talked more about the principles rather than the practical consequences.It was only once we went live with Mercurial and a sub-repo, that I really understood the advice properly. Here (from memory) are examples of the sorts of problems we encountered.Your users will end up fighting the update and merge process.Some people will update the parent repo and not the sub-repoSome people will push from the sub-repo, ang .hgsubstate won't get updated.You will end up "losing" revisions that were made in the sub-repo, because someone will manage to leave the .hgsubstate in an incorrect state after a merge.Some users will get into the situation where the .hgsubstate has been updated but the sub-repo hasn't, and then you'll get really cryptic error messages, and will spend many hours trying to work out what's going on.And if you do tagging and branching for releases, the instructions for how to get this right for both parent and sub-repo will be many dozens of lines long. (And I even had a nice, tame Mercurial expert help me write the instructions!)All of these things are annoying enough in the hands of expert users - but when you are rolling out Mercurial to novice users, they are a real nightmare, and the source of much wasted time.So, having put in a lot of time to get a conversion with a sub-repo, several weeks later we then converted the sub-repo to a repo. Because we had large amounts of history in the conversion that referred to the sub-repo, via .hgsubstate, it's left us with something much more complicated.I only wish I'd really appreciated the practical consequences of all the advice much earlier on, e.g. in Mercurial's Features of Last Resort page:Edit: Thoughts on shell reposWith the disclaimer I don't have any experience of them...No, I don't think many of them are. You are still using sub-repos, so all the same user issues apply (unless you can provide a wrapper script for every step, of course, to remove the need for humans to supply the correct options to handle sub-repos.)Also note that the wiki page you quoted does list some specific issues with shell repos:Edit 2 - do a trial, involving all your usersThe point at which we really started realising we had an issue was once multiple users started making commits, and pulling and pushing - including changes to the sub-repo. For us, it was too late in the day to respond to these issues. If we'd known them sooner, we could have responded much more easily and simply.So at this point, the best advice I think I can offer is to recommend that you do a trial run of the project layout before the layout is carved in stone.We left the full-scale trial until too late to make changes, and even then people only made changes in the parent repo, and not the sub-repos - so we still didn't see the full picture until too late.In other words, whatever layout you consider, create a repository structure in that layout, and get lots of people making edits. Try to put enough real code into the various repos/sub-repos so that people can make real edits, even though they will be throw-way ones.Possible outcomes:You might find it all works fine - in which case, you'll have spent some time to gain certainty.On the other hand, you might identify issues much more quickly than spending time trying to work out what the outcomes would beAnd your users will learn a lot too. 这篇关于如何使用Mercurial子存储库共享组件和依赖项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
07-16 12:20
查看更多