12

简介和背景

我们正在更改源代码控制系统,我们目前正在评估 git 和 mercurial。总代码库大约有 600 万行代码,所以不算大,也不算小。

让我首先简要介绍一下当前存储库设计的外观。

我们有一个用于完整代码库的基本文件夹,在该级别之下,有各种不同的上下文中使用的各种模块。例如,“dllproject1”和“dllproject2”可以被视为完全独立的项目。

我们正在开发的软件是我们称之为配置器的东西,它可以根据不同的客户需求进行无休止的定制。我们总共可能有 50 个不同的版本。然而,他们有一个共同点。它们都共享几个强制性模块(mandatory_module1 ..)。这些文件夹基本上包含内核/核心代码和公共语言资源等。然后,所有自定义都可以是其他模块(module1 ..)之间的任意组合。

由于我们目前使用的是 cvs,因此我们在 CVSROOT/modules 文件中添加了别名。它们可能看起来像:

core –a mandatory_module1 mandatory_module2 mandatory_module3
project_x –a module1 module3 module5 core

因此,如果有人决定在 project_x 上工作,他/她可以快速检查以下所需的模块:

base>cvs co project_x

问题

直觉上,将基本文件夹作为单个存储库感觉是错误的。作为程序员,您应该能够检查您正在使用的当前项目所需的确切代码子集。您对此有何看法?

另一方面,将这些模块中的每一个放在单独的存储库中感觉更合适。但这使得程序员更难检查他们需要的模块。您应该能够通过单个命令来执行此操作。所以我的问题是:在 git/mercurial 中是否有类似的定义别名的方法?

任何其他问题,建议,指针都非常欢迎!

PS。我已经搜索过类似的问题,但并不觉得其中任何一个问题 100% 地适用于我的情况。

4

2 回答 2

13

只是一个简短的评论来提醒你:

  • 这些迁移通常提供了重新组织源的机会,而不是沿着模块(每个模块都有一个存储库),而是沿着功能域拆分(相同给定功能域的几个模块放在同一个存储库中)。

然后将使用子模块作为定义配置的一种方式。

  • Git 没问题,但是从Linus 自己的承认来看,将所有内容都放在一个存储库中可能会出现问题。

[...] CVS,即它实际上最终非常面向“一次一个文件”模型。

这很好,因为您可以拥有一百万个文件,然后只检查其中的几个 - 您甚至永远不会看到其他 999,995 个文件的影响。

Git 从根本上说从来没有真正关注过整个 repo。即使你稍微限制了一些事情(即只检查一部分,或者让历史回溯一点),git 最终仍然总是关心整个事情,并随身携带知识。

所以如果你强迫 git 把所有东西都看成一个 巨大的存储库,那么它的扩展性就会非常糟糕。我不认为这部分是真正可以修复的,尽管我们可能可以改进它。

是的,然后是“大文件”问题。我真的不知道如何处理大文件。我们很讨厌他们,我知道。


上述两点主张为大型系统(和大型遗留存储库)采用更加面向组件的方法。

使用Git submodule,您可以在项目中签出它们(即使它是一个两步过程)。但是,您拥有可以使子模块管理更容易的工具(例如git.rake)。


当我考虑修复在多个项目之间共享的模块中的错误时,我只是修复错误并提交它,然后所有人都只是进行更新

这就是我在Vendor Branch中描述的“系统方法”:每个人都在最新的(HEAD)上工作,它对少数项目有效。
尽管对于大量的模块,“模块”的概念仍然非常有用,但它的管理与 DVCS 不同:

  • 对于密切相关的模块(又名“在同一功能域中”,例如“与 PNL 相关的所有模块 - 利润和损失 - 或“风险分析”,在金融领域),您确实需要使用最新的 (HEAD)所有涉及的组件。
    这将通过使用子树策略来实现,不是为了让您发布(推送)对那些其他子模块的更正,而是为了跟踪其他团队所做的工作
    。Git 允许这样做的额外奖励是这种“跟踪”不必在您的存储库和一个“中央”存储库之间进行,也可以在您和另一个团队的本地存储库之间进行,从而允许非常快速的来回集成和测试类似性质的项目。

  • 但是,对于不直接在您的功能域中的模块,子模块是更好的选择,因为它们指的是模块的修复版本(提交):
    当低级框架发生更改时,您不希望它被传播瞬间,因为它会影响所有其他团队,然后他们将不得不放弃他们正在做的事情以使他们的代码适应那个新版本(你确实希望所有其他团队都知道这个新版本,以便他们不要忘记更新该低级组件或“模块”)。
    这允许您仅使用其他模块的官方稳定识别版本,而不是潜在的不稳定或未完全测试的 HEAD。

于 2009-05-22T18:54:40.783 回答
5

至于 Mercurial 方面,建议还将大型遗留 CVS/SVN 存储库重构为更小的组件。公共代码应该放入自己的库中,然后应用程序代码将依赖于这些库,就像它依赖于其他库一样。

Mercurial 具有森林扩展,允许您管理“源树”的“森林”。使用这种方法,您可以将几个较小的存储库组合成一个较大的存储库。使用 CVS,您可以做相反的事情:您签出大型存储库的一小部分。

我没有亲自使用过森林扩展,它的页面说与 Mercurial 捆绑的版本相比,应该使用更新版本。但是,像 Sun 这样的大型组织在其OpenJDK 项目使用它。

根据 Mercurial wiki 中嵌套存储库页面的设计,目前还正在进行将子存储库报告直接添加到 Mercurial 核心的工作。

于 2009-05-24T18:40:10.327 回答