gpt4 book ai didi

mercurial - 如何将 mercurial subrepos 用于共享组件和依赖项?

转载 作者:行者123 更新时间:2023-12-02 11:50:16 25 4
gpt4 key购买 nike

我们用 C# 开发 .NET 企业软件。我们正在寻求改进我们的版本控制系统。我之前使用过 mercurial,并且一直在我们公司尝试使用它。但是,由于我们开发企业产品,因此我们非常关注可重用的组件或模块。我一直在尝试使用 mercurial 的 sub-repos 来管理组件和依赖项,但遇到了一些困难。以下是源代码控制/依赖项管理的基本要求:

  • 可重用组件
  • 源共享(用于调试)
  • 依赖于 3rd 方二进制文件和其他可重用组件
  • 可以在消费产品
  • 的上下文中开发并致力于源代码控制
  • 依赖关系
  • 产品依赖于第 3 方二进制文件和其他可重用组件
  • 依赖有自己的依赖
  • 应通知开发人员依赖项中的版本冲突

  • 这是我一直在使用的 mercurial 结构:

    一个可重用的组件:
    SHARED1_SLN-+-docs
    |
    +-libs----NLOG
    |
    +-misc----KEY
    |
    +-src-----SHARED1-+-proj1
    | +-proj2
    |
    +-tools---NANT

    第二个可重用组件,使用第一个:
    SHARED2_SLN-+-docs
    |
    +-libs--+-SHARED1-+-proj1
    | | +-proj2
    | |
    | +-NLOG
    |
    +-misc----KEY
    |
    +-src-----SHARED2-+-proj3
    | +-proj4
    |
    +-tools---NANT

    消耗两种成分的产品:
    PROD_SLN----+-docs
    |
    +-libs--+-SHARED1-+-proj1
    | | +-proj2
    | |
    | +-SHARED2-+-proj3
    | | +-proj4
    | |
    | +-NLOG
    |
    +-misc----KEY
    |
    +-src-----prod----+-proj5
    | +-proj6
    |
    +-tools---NANT

    笔记
  • repo 在大写
  • 假定所有子存储库都是子存储库
  • 3rd 方(二进制)库和内部(源)组件都是位于库文件夹
  • 中的子存储库
  • 3rd 方库保存在单独的 mercurial 存储库中,以便使用项目可以引用库的特定版本(即旧项目可能引用 NLog v1.0,而较新的项目可能引用 NLog v2.0)。
  • 所有 Visual Studio .csproj 文件都在第 4 级(proj* 文件夹),允许对依赖项的相对引用(即 ../../../libs/NLog/NLog.dll 用于所有引用 NLog 的 Visual Studio 项目)
  • 所有 Visual Studio .sln 文件都在第 2 级(src 文件夹),因此在将组件“共享”到消费组件或产品中时不包括它们
  • 开发人员可以自由组织他们认为合适的源文件,只要源是消费 Visual Studio 项目的 proj* 文件夹的子级(即,proj* 文件夹可以有 n 个子级,包含各种源/资源)
  • 如果 Bob 正在开发 SHARED2 组件和 PROD1 产品,那么他在 PROD1_SLN 存储库中更改 SHARED2 源(比如属于 proj3 的源)并提交这些更改是完全合法的。我们不介意是否有人在消费项目的上下文中开发库。
  • 内部开发的组件(SHARED1 和 SHARED2)通常由源包含在使用项目中(在 Visual Studio 中添加对项目的引用而不是浏览到 dll 引用)。这允许增强调试(步入库代码),允许 Visual Studio 管理何时需要重建项目(当依赖项被修改时),并允许在需要时修改库(如上述说明中所述)。

  • 问题
  • 如果 Bob 在 PROD1 上工作而 Alice 在 SHARED1 上工作,Bob 如何知道 Alice 何时提交对 SHARED1 的更改。目前使用 Mercurial,Bob 被迫在每个子仓库中手动拉取和更新。如果他从 PROD_SLN 存储库推送/拉取到服务器,他永远不会知道子存储库的更新。这在 Mercurial wiki 中有描述。当 Bob 从服务器拉取最新的 PROD_SLN 时,如何通知他 subrepos 的更新?理想情况下,他应该得到通知(最好在拉取期间),然后必须手动决定他想要更新哪个子存储库。
  • 假设 SHARED1 引用 NLog v1.0(mercurial 中的 commit/rev abc)和 SHARED2 引用 Nlog v2.0(mercurial 中的 commit/rev xyz)。如果 Bob 在 PROD1 中吸收了这两个组件,他应该意识到这种差异。虽然从技术上讲 Visual Studio/.NET 将允许 2 个程序集引用不同版本的依赖项,但我的结构不允许这样做,因为 NLog 的路径对于所有依赖 NLog 的 .NET 项目都是固定的。 Bob 怎么知道他的两个依赖项存在版本冲突?
  • 如果 Bob 正在为 PROD1 设置存储库结构并希望包含 SHARED2,他如何知道 SHARED2 需要哪些依赖项?使用我的结构,他必须手动克隆(或在服务器上浏览)SHARED2_SLN 存储库,然后查看 libs 文件夹,或查看 .hgsub 文件以确定他需要包含哪些依赖项。理想情况下,这将是自动化的。如果我在我的产品中包含 SHARED2,SHARED1 和 NLog 也会自动神奇地包含在内,通知我是否与其他依赖项存在版本冲突(请参阅上面的问题 2)。

  • 更大的问题
  • mercurial 是正确的解决方案吗?
  • 有没有更好的mercurial结构?
  • 这是否可用于 subrepos(即 Mercurial 开发人员将 subrepos 标记为最后的功能)?
  • 使用 mercurial 进行依赖管理有意义吗?我们可以使用另一种工具进行依赖项管理(可能是内部 NuGet 提要?)。虽然这对于 3rd 方依赖很有效,但它确实会给内部开发的组件带来麻烦(即,如果它们被积极开发,开发人员将不得不不断更新提要,我们将不得不在内部为它们提供服务,这将不允许由消费项目修改的组件(注释 8 和问题 2)。
  • 对于企业 .NET 软件项目,您有更好的解决方案吗?

  • 引用

    我已经阅读了几个 SO 问题,发现 this one 很有帮助,但 accepted answer 建议使用专用的依赖工具。虽然我喜欢这种工具的特性,但它不允许从消费项目中修改和提交依赖项(请参阅更大的问题 4)。

    最佳答案

    这可能不是您想要的答案,但我们最近有使用子存储库的 Mercurial 新手用户的经验,我一直在寻找机会来传递我们的经验......

    综上所述,我根据经验的建议是:不管 Mercurial sub-repos 有多么吸引人,都不要使用它们 .相反,找到一种方法来并排布置您的目录,并调整您的构建以应对这种情况。

    不管将子 repo 中的修订与父 repo 中的修订联系起来似乎很有吸引力,但它在实践中不起作用。

    在转换的所有准备过程中,我们收到了来自多个不同来源的建议,认为子存储库很脆弱且没有很好地实现——但我们还是继续了,因为我们希望在存储库和子存储库之间进行原子提交。建议——或者我对它的理解——更多地谈论了原则而不是实际后果。

    只有当我们使用 Mercurial 和一个子仓库时,我才真正正确地理解了这些建议。这里(从内存中)是我们遇到的各种问题的例子。

  • 您的用户最终将与更新和合并过程作斗争。
  • 有些人会更新父仓库而不是子仓库
  • 有些人会从 sub-repo 推送,ang .hgsubstate 不会更新。
  • 您最终将“丢失”在子存储库中所做的修订,因为有人会在合并后设法使 .hgsubstate 处于不正确的状态。
  • 一些用户会遇到 .hgsubstate 已更新但子存储库尚未更新的情况,然后您会收到非常神秘的错误消息,并且会花费很多时间试图弄清楚发生了什么。
  • 如果你为发布做标记和分支,关于如何为父和子存储库正确设置的说明将有几十行长。 (我什至有一位友善、温和的 Mercurial 专家帮助我编写说明!)

  • 所有这些东西在专家用户手中已经够烦人了——但是当您向新手用户推出 Mercurial 时,它们确实是一场噩梦,并且是浪费大量时间的根源。

    因此,花了很多时间来转换子 repo ,几周后,我们将子 repo 转换为 repo 。因为我们在通过 .hgsubstate 引用子存储库的转换中有大量历史记录,所以它给我们留下了更复杂的东西。

    我只希望我真的很早就意识到所有建议的实际后果,例如在 Mercurial 的 Features of Last Resort页:

    But I need to have managed subprojects!

    Again, don't be so sure. Significant projects like Mozilla that have tons of dependencies do just fine without using subrepos. Most smaller projects will almost certainly be better off without using subrepos.



    编辑:关于 shell repos 的想法

    有了免责声明,我对他们没有任何经验......

    不,我认为他们中的很多人都不是。您仍在使用子存储库,因此所有相同的用户问题都适用(除非您可以为每个步骤提供包装脚本,当然,以消除人类提供正确选项来处理子存储库的需要。)

    另请注意,您引用的 wiki 页面确实列出了 shell 存储库的一些特定问题:

    • overly-strict tracking of relationship between project/ and somelib/
    • impossible to check or push project/ if somelib/ source repo becomes
    • unavailable lack of well-defined support for recursive diff, log, and
    • status recursive nature of commit surprising


    编辑 2 - 进行试验,涉及所有用户

    我们真正开始意识到我们遇到了问题的那一点是,一旦多个用户开始提交、拉取和推送——包括对子存储库的更改。对我们来说,现在对这些问题做出回应为时已晚。如果我们早点认识他们,我们本可以更轻松、更简单地做出回应。

    所以在这一点上,我认为我能提供的最好建议是推荐您 版面石刻前先做项目版面的试运行 .

    我们将全面的试验拖到太晚无法进行更改,即使那样人们也只在父存储库中进行了更改,而不是在子存储库中进行了更改 - 所以我们直到太晚才看到全貌。

    换句话说,无论您考虑什么布局,在该布局中创建一个存储库结构,并让很多人进行编辑。尝试将足够多的真实代码放入各种 repos/sub-repos,以便人们可以进行真正的编辑,即使它们将是废弃的。

    可能的结果:
  • 您可能会发现一切正常 - 在这种情况下,您将花费一些时间来确定。
  • 另一方面,您可能会比花时间试图找出结果会更快地发现问题
  • 你的用户也会学到很多东西。
  • 关于mercurial - 如何将 mercurial subrepos 用于共享组件和依赖项?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11628301/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com