20

我知道在版本控制中至少有 10 种不同的方式来构建项目。我很好奇正在使用哪些方法以及哪些方法适合您。我曾使用过 SVN、TFS 和目前/不幸的是 VSS。我已经看到版本控制实施得非常糟糕而且还不错,但从来都不是很好。

只是为了让球滚动,这里是我所看到的事情的回顾。

这个例子是基于 SVN 的,但适用于大多数 VCS(对分布式版本控制不太适用)。

  1. 分支属于站点 /division/web/projectName/vb/src/[trunk|branches|tags] 的各个项目

  2. 分支整个站点,在我看到的情况下,除了核心组件之外的整个站点都被分支了。/division/[主干|分支|标签]/web/projectName/vb/src/

  3. 默认使用主线,仅在需要进行巨大更改时才分支。

4

9 回答 9

10

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:

svnrepo/
  trunk/
    modules/
      m1/ --> will result in jar file
      m2/
      ...
    assemblies/
      a1/
      ...
  tags/
    modules/
      m1/
        1.0.0/
        1.0.1/
        1.1.0/
       m2/
      ...
    assemblies/
      a1/
        iteration-55/
        ...
  branches/
    m1/
      1.0/
      ...

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.

于 2008-08-19T20:43:39.897 回答
7

SVN 示例:

树干/

分支/

标签/

后备箱应保持在您可以随时从中释放的位置。不应该有你知道的巨大的漏洞(当然最终会有,但这是你应该努力的)。

每次您需要制作新功能时,请进行设计更改,无论如何,分支。在开始时标记该分支。然后,当您完成分支标签时,它会在最后。这有助于合并回主干。

每次你需要推送一个版本,标记。这样,如果出现严重错误,您可以回滚到以前的版本。

此设置使主干尽可能干净,并允许您快速修复错误并将其推出,同时将大部分开发保留在分支中。

编辑:对于第 3 方的东西,这取决于。如果我能避免它,我就没有它在源代码控制之下。我将它保存在源代码控制之外的目录中并从那里包含它。对于 jquery 之类的东西,我确实将其置于源代码控制之下。原因是它简化了我的推送脚本。我可以简单地让它做一个 svn 导出和 rsync。

于 2008-08-19T20:09:33.367 回答
6

For my projects, I always use this structure.

  • trunk
    • config
    • docs
    • sql
      • initial
      • updates
    • src
      • app
      • test
    • thirdparty
      • lib
      • tools
  • tags
  • branches
  • config - Used to store my application config templates. During the build process, I take these templates and replace token placeholders with actual values depending on what configuration I am making the build.
  • docs - Any application documentation gets placed in here.
  • sql - I break my sql scripts into two directories. One for the initial database setup for when you are starting fresh and another place for my update scripts which get ran based on the version number of the database.
  • src - The application source files. In here I break source files based on application and tests.
  • thirdparty - This is where I put my third party libraries that I reference inside of my application and not available in the GAC. I split these up based on lib and tools. The lib directory holds the libraries that need to be included with the actual application. The tools directory holds the libraries that my application references, but are only used for running unit tests and compiling the application.

My solution file gets placed right under the trunk directory along with my build files.

于 2008-08-19T20:39:42.103 回答
2

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.

于 2008-08-19T21:02:49.420 回答
2

由于我们在同一棵树中拥有所有工件和构造,因此我们有以下内容:

  • 树干

    • 规划与追踪
    • 请求
    • 设计
    • 建造
      • 垃圾桶
      • 数据库
      • 资源
  • 部署

  • 质量保证
于 2008-09-16T14:48:24.830 回答
2

我更喜欢细粒度、非常有组织、自包含、结构化的存储库。有一个图表说明了存储库维护过程的一般(理想)方法。例如,我最初的存储库结构(每个项目存储库都应该有)是:

/project
    /trunk
    /tags
        /builds
            /PA
            /A
            /B
        /releases
            /AR
            /BR
            /RC
            /ST
    /branches
        /experimental
        /maintenance
            /versions
            /platforms
        /releases

PA表示pre-alpha A 表示alpha B 表示beta AR表示alpha-release BR表示beta-release RC表示候选版本 ST表示稳定

构建发布之间存在差异。

  • builds文件夹下的标签具有对应于模式的版本号N.x.K,其中NK是整数。示例:1.x.0, 5.x.1,10.x.33
  • 发布文件夹下的标签具有对应于模式的版本号,N.M.K其中和是整数。例子:, , .NMK1.0.05.3.110.22.33

最近我开发了专门针对软件配置管理的培训,我在其中描述了版本编号方法以及为什么这个存储库结构是最好的。这是演示幻灯片

关于“多个 SVN 存储库与单个公司存储库”的问题,我也有回答。只要您在问题中解决存储库结构的这一方面,它可能会有所帮助。

于 2012-01-19T16:34:15.613 回答
1

我认为团队采用的 SCM 政策和程序将非常依赖于他们使用的开发过程。如果你有一个 50 人的团队,有几个人同时进行重大更改,并且每 6 个月才发布一次,那么每个人都有自己的分支是很有意义的,他可以在其中独立工作并且只合并来自当他想要其他人时。另一方面,如果你是一个 5 人的团队,都坐在同一个房间里,那么少分派是有意义的。

假设您在一个沟通和协作良好且发布频繁的小团队中工作,那么对 IMO 进行分支几乎没有意义。在一个项目中,我们只是简单地将 SVN 修订号添加到我们所有版本的产品版本号中,我们甚至从未标记。在极少数情况下,在 prod 中发现严重错误,我们会直接从已发布的修订版中直接分支。但大多数时候我们只是简单地修复了分支中的错误,并按计划在周末从主干发布。如果您的发布足够频繁,您几乎永远不会遇到不能等到下一个正式发布的错误。

我曾参与过其他我们永远无法摆脱的项目,但由于轻量级开发过程和低仪式,我们能够非常有效地使用轻量级版本控制策略。

我还要提到,我编写的所有内容都来自企业 IT 环境,其中给定代码库只有一个生产实例。如果我正在开发一个部署在 100 个不同客户站点的产品,那么分支和标记实践必须更加费力才能管理所有实例中的所有独立更新周期。

于 2008-08-19T20:24:52.460 回答
1

What about external dependencies such a the AJAXTookit or some other 3rd party extension that's used on several projects?

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.

于 2008-08-19T20:29:42.950 回答
0

在切换到 SVN 之前,我们使用一个巨大的存储库(超过 4G)从 VSS 的糟糕世界中迁移出来。我真的很纠结如何为我们公司设置新的存储库。我们公司是很“老”的学校。很难得到改变我是年轻的开发者之一,我已经 45 岁了!我是公司开发团队的一员,该团队为我们公司的多个部门开展项目。无论如何,我这样设置我们的目录

+ devroot
    +--Dept1
        +--Dept1Proj1
        +--Dept2Proj2
    +--Dept2
        +--Dept2Proj1
    +--Tools
        +--Purchase3rdPartyTools
        +--NLog
        +--CustomBuiltLibrary

我想包括分支的能力,但老实说,这在这一点上太过分了。有几件事我们仍然在努力使用这个方案。

  • 如果您正在进行重大产品升级(即因为我们不进行分支),则很难解决生产问题
  • 从“Dev”提升到“Prod”的概念很难管理。(甚至不要问关于提升到 QA 的问题)
于 2008-08-20T02:59:28.240 回答