版本控制中的项目结构
我知道在版本控制中至少有 10 种不同的方式来构建项目。 我很好奇正在使用的一些方法是什么以及哪些方法适合您。 我曾经使用过 SVN、TFS,目前/不幸的是 VSS。 我见过版本控制的实现非常糟糕,也还可以,但从来都不是很好。
为了让事情顺利进行,这里是我所看到的事情的回顾。
此示例基于 SVN,但适用于大多数 VCS(不适用于分布式版本控制)。
对属于站点一部分的各个项目进行分支 /division/web/projectName/vb/src/[trunk|branches|tags]
对整个站点进行分支,在我所看到的情况下,除了核心组件之外的整个站点都被分支。 /division/[trunk|branches|tags]/web/projectName/vb/src/
默认使用主线,仅在需要进行巨大更改时才使用分支。
I know there are at least 10 different ways to structure project in version control. I'm curious what some methods being used are and which ones work for you. I've worked with SVN, TFS, and currently/unfortunately VSS. I've seen version control implemented very poorly and just OK, but never great.
Just to get the ball rolling, here is a review of things I've seen.
This example is SVN-based, but applies to most VCS's (not so much to distributed version control).
branch the individual projects that are part of site
/division/web/projectName/vb/src/[trunk|branches|tags]branch the whole site, in the case I've seen, the whole site except for core components was branched.
/division/[trunk|branches|tags]/web/projectName/vb/src/Use main-line a default, only branch when necessary for huge changes.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
源代码控制针对的是源代码,而不是二进制文件。 将任何第 3 方程序集/jar 保存在单独的存储库中。 如果您在 Java 领域工作,请尝试 Maven 或 Ivy 之类的工具。 对于 .Net 项目,只要您有关于其结构和更新方式的适当策略,简单的共享驱动器就可以很好地工作。
Source control is for source code, not binaries. Keep any 3rd party assemblies/jars in a separate repository. If you're working in the Java world try something like Maven or Ivy. For .Net projects a simple shared drive can work well as long as you have decent policies around how it's structured and updated.
在切换到 SVN 之前,我们从拥有一个巨大存储库(超过 4G)的 VSS 的糟糕世界中迁移出来。 我真的很纠结如何为我们公司建立新的存储库。 我们公司是很“老”的学校。 想要改变是很困难的,我是年轻的开发者之一,而且我已经 45 岁了! 我是企业开发团队的一员,该团队为公司的多个部门开发项目。 不管怎样,我像这样设置了我们的目录,
我想包括分支的能力,但老实说,在这一点上这太多了。 有一些事情我们在使用这个方案时仍然遇到困难。
We migrated from the bad world of VSS with one giant repository (over 4G) before switching to SVN. I really struggled with how to set up the new repository for our company. Our company is very "old" school. It's difficult to get change I'm one of the younger developers and I'm 45! I am part of a corporate development team that works on programs for a number of departments in our company. Anyway I set up our directories like this
I wanted to include the ability to branch, but quite honestly that's just too much at this point. Couple things we still struggle with using this scheme.
SVN 示例:
trunk/
branch/
tags/
trunk 应保存在您始终可以从中推送版本的位置。 不应该存在您所知道的巨大缺陷(当然最终会有,但这就是您应该努力的目标)。
每次你需要制作一个新功能时,都要进行设计更改,无论如何,分支。 在开头标记该分支。 然后,当您完成分支后,将其标记在最后。 这有助于合并回主干。
每次您需要推送版本时,请标记。 这样,如果出现严重错误,您可以回滚到以前的版本。
此设置使主干尽可能保持干净,并允许您快速修复错误并将其推出,同时将大部分开发保留在分支中。
编辑: 对于第 3 方的东西,这取决于。 如果我可以避免它,我就不会将其置于源代码控制之下。 我将其保存在源代码管理之外的目录中,并从那里包含它。 对于像 jquery 这样的东西,我确实将其置于源代码控制之下。 原因是它简化了我的推送脚本。 我可以简单地让它执行 svn 导出和 rsync。
Example for SVN:
trunk/
branch/
tags/
The trunk should be kept at a point where you can always push a release from it. There should be no huge gaping bugs that you know about(of course there will be eventually but that is what you should strive for).
Every time you need to make a new feature, do a design change, whatever, branch. Tag that branch at the start. Then when you are finished with the branch tag it at the end. This helps out with merging back into trunk.
Every time you need to push a release, tag. This way if something goes horribly wrong you can rollback to the previous release.
This setup keeps trunk as clean as possible and allows you to make quick bug fixes and push them out while keeping the majority of your development in branches.
Edit: For 3rd party stuff it depends. If I can avoid it I do not have it under source control. I keep it in a directory outside source control and include it from there. For things like jquery, I do leave it under source control. The reason is it simplifies my script for pushing. I can simply have it do an svn export and rsync.
我可以理解不将二进制文件放入存储库的逻辑,但我认为这也有一个巨大的优势。 如果你希望能够从过去(通常是较旧的标签)中提取特定的修订版本,我喜欢能够从 svn checkout 获得我需要的一切。 当然,这不包括 Visual Studio 或 .NET 框架,但拥有正确版本的 nant、nunit、log4net 等使得从结账到构建变得非常容易。 这种入门方式就像“svn co project”然后“nant build”一样简单。
我们做的一件事是将第三方二进制文件放在一个单独的树中,并使用 svn:external 为其提供我们需要的版本。 为了让生活变得轻松,我们将为每个已使用的版本提供一个文件夹。 例如,我们可以将 ThirdParty/Castle/v1.0.3 文件夹引入当前项目。 这样,构建/测试产品所需的所有内容都位于项目根内部或之下。 根据我们的经验,磁盘空间的权衡是非常值得的。
I can appreciate the logic of not putting binaries in the repository but I think there is a huge advantage too. If you want to be able to pull a specific revision out from the past (usually an older tag) I like being able to have everything I need come from the svn checkout. Of course this doesn't include Visual Studio or the .NET framework but having the right version of nant, nunit, log4net, etc. makes it really easy to go from checkout to build. This way getting started is as easy as "svn co project" followed by "nant build".
One thing we do is put ThirdParty binaries in a separate tree and use svn:external to bring it the version we need. To make life easy, we'll have a folder for each version that has been used. For example, we might bring in the ThirdParty/Castle/v1.0.3 folder to the current project. This way everything need to build/test the product is inside or below the project root. The tradeoff in disk space is well worth it in our experience.
对于我的项目,我总是使用这种结构。
我的解决方案文件与我的构建文件一起放置在 trunk 目录下。
For my projects, I always use this structure.
My solution file gets placed right under the trunk directory along with my build files.
我认为团队采用的 SCM 政策和程序将非常依赖于他们正在使用的开发流程。 如果您有一个 50 人的团队,其中几个人同时致力于重大变更,并且每 6 个月才发布一次,那么每个人都拥有自己的分支是很有意义的,他可以在其中独立工作,并且只合并来自当他想要其他人时。 另一方面,如果您是一个 5 人团队,全部坐在同一个房间里,那么减少分支频率是有意义的。
假设您在一个小团队中工作,该团队的沟通和协作良好并且发布频繁,那么在我看来,建立分支几乎没有任何意义。 在一个项目中,我们只是将 SVN 修订号添加到所有版本的产品版本号中,甚至从未进行标记。 在极少数情况下,在产品中发现严重错误时,我们将直接从已发布的修订版本中分支出来。 但大多数时候我们只是修复了分支中的 bug,并按计划在周末从主干发布。 如果您的发布足够频繁,您几乎永远不会遇到迫不及待下一个正式版本的错误。
我曾参与过其他项目,但我们永远无法摆脱这一点,但由于轻量级开发过程和低仪式,我们能够非常有效地使用轻量级版本控制策略。
我还要提到的是,我编写的所有内容都来自企业 IT 环境,其中给定代码库只有一个生产实例。 如果我正在开发一个部署在 100 个不同客户站点的产品,那么分支和标记实践就必须更加费劲,以便管理所有实例中的所有独立更新周期。
I think the SCM policies and procedures a team adopts are going to be very dependent on the development process they are using. If you've got a team of 50 with several people working on major changes simultaneously and releases only occurring every 6 months, it makes a lot of sense for everyone to have his own branch where he can work in isolation and only merge in changes from other people when he wants them. On the other hand, if you're a team of 5 all sitting in the same room it makes sense to branch much less frequently.
Assuming you're working on a small team where communication and collaboration is good and releases are frequent, it makes very little sense to ever branch IMO. On one project we simply rolled the SVN revision number into the product version number for all our releases and we never even tagged. In the rare event that there was a critical bug found in prod we would simply branch straight from the revision that was released. But most of the time we simply fixed the bug in the branch and released from trunk at the end of the week as scheduled. If your releases are frequent enough you'll almost never run into a bug that can't wait until the next official release.
I've worked on other projects where we never could have gotten away with that, but due to the lightweight development process and low ceremony we were able to use a lightweight version control policy very effectively.
I'll also mention that everything I've written is coming from an enterprise IT context where there's only a single production instance of a given code base. If I was working on a product that was deployed at 100 different customer sites the branching and tagging practices would have to be a little more strenuous in order to manage all of the independent update cycles across all the instances.
我们使用Java进行高度组件化的开发,主干中有大约250个具有独立生命周期的模块。 依赖关系通过 Maven 进行管理(这是最佳实践),每次迭代(每两周一次)积极开发的模块都会被标记为新版本。 具有严格语义的 3 位版本号(major.minor.build - 主要更改意味着向后不兼容,次要更改意味着向后兼容,内部版本号更改意味着向后和向前兼容)。 我们的最终软件产品是一个集合,它引入了数十个单独的模块,同样作为 Maven 依赖项。
当我们需要对已发布版本进行错误修复或增强并且无法提供 HEAD 版本时,我们会分支模块/程序集。 标记所有版本使得这很容易做到,但分支仍然会产生大量的管理开销(特别是保持分支与某些 HEAD 更改集同步),部分原因是我们的工具造成的,Subversion 对于管理分支来说不是最佳选择。
我们发现存储库中相当平坦且最重要的是可预测树结构至关重要。 它使我们能够构建发布工具,消除手动发布过程中的许多痛苦和危险(更新的发行说明、项目编译、运行单元测试、制作标签、无快照依赖项等)。 避免在树结构中放置过多的分类或其他逻辑。
我们大致做了如下的事情:
对于外部依赖项,我怎么强调都不过分,比如 Maven:管理您的依赖项,将其作为对存储库中版本化、唯一标识的二进制工件的引用。
对于内部模块/项目结构:坚持标准。 一致性是关键。 同样,Maven 可以在这里提供帮助,因为它规定了一个结构。 许多结构都很好,只要你坚持下去。
We practice highly componentised development using Java, we have about 250 modules in trunk that have independent life cycles. Dependencies are managed through Maven (that's a best practice right there), every iteration (bi-weekly) actively developed modules get tagged with a new version. 3 digit version numbers with strict semantics (major.minor.build - major changes means backwards incompatible, minor changes mean backwards compatible and build number changes mean backwards and forwards compatible). Our ultimate software product is an assembly that pulls in dozens of individual modules, again as Maven dependencies.
We branch modules/assemblies when we need to make a bug fix or enhancement for a released version and we can not deliver the HEAD version. Having tagged all versions makes this easy to do but branches still incur a significant administrative overhead (specifically keeping branches in sync with certain HEAD changesets) that are partly caused by our tools, Subversion is sub-optimal for managing branches.
We find that a fairly flat and above all predictable tree structure in the repository is crucial. It has allowed us to build release tools that take away a lot of the pain and danger from a manual release process (updated release notes, project compiles, unit tests run through, tag is made, no SNAPSHOT dependencies, etc). Avoid putting too much categorization or other logic in your tree structure.
We roughly do something like the following:
For external dependencies, I can not overemphasize something like Maven: manage your dependencies as references to versioned, uniquely identified binary artifacts in a repository.
For intenal module/project structure: stick to a standard. Uniformity is key. Again, Maven can help here since it dictates a structure. Many structures are fine, as long as you stick to them.
我更喜欢细粒度的、非常有组织的、独立的、结构化的存储库。 有一个图表说明了存储库维护过程的一般(理想)方法。 例如,我的存储库的初始结构(每个项目存储库都应该有)是:
PA
表示 pre-alphaA
表示 alphaB
表示测试版AR
表示 alpha 版本BR
表示测试版RC
表示候选版本ST
表示稳定。构建和发布之间存在差异。
NxK
相对应的版本号,其中N
和K 是整数。 示例:
1.x.0
、5.x.1
、10.x.33
标签文件夹的版本号对应于模式NMK
,其中N
、M
和K
是整数。 示例:1.0.0
、5.3.1
、10.22.33
。最近,我开发了专门针对软件配置管理的培训,其中我描述了版本编号方法以及为什么这个存储库结构是最好的。 以下是演示幻灯片。
答案 ="https://stackoverflow.com/questions/1761513/multiple-svn-repositories-or-single-company-repository/1762051">关于“多个 SVN 存储库与单个公司存储库”的问题。 只要您在问题中解决存储库结构的这个方面,它可能会有所帮助。
I prefer fine-grained, very organized, self contained, structured repositories. There is a diagram illustrating general (ideal) approach of repository maintenance process. For example, my initial structure of repository (every project repository should have) is:
PA
means pre-alphaA
means alphaB
means betaAR
means alpha-releaseBR
means beta-releaseRC
means release candidateST
means stableThere are differences between builds and releases.
N.x.K
, whereN
andK
are integers. Examples:1.x.0
,5.x.1
,10.x.33
N.M.K
, whereN
,M
andK
are integers. Examples:1.0.0
,5.3.1
,10.22.33
.Recently I have developed training dedicated to Software Configuration Management where I describe version numbering approach and why exactly this repository structure is the best. Here are presentation slides.
There is also my answer on the question about 'Multiple SVN Repositories vs single company repository'. It might be helpful as long as you address this aspect of repository structuring in your question.
由于我们将所有工件和构造都放在同一棵树中,因此我们有如下内容:
Trunk
部署
As we have all the artifacts and construction in the same tree we have something like:
Trunk
Deploy