【问题标题】:Dependency Management In SCMSCM中的依赖管理
【发布时间】:2013-04-23 19:17:48
【问题描述】:

为了争论,假设我正在开发一个项目 X,它有一个依赖项 Y。现在 Y 是一个独立的开源项目,由第三方定期维护和更新。我检查了 Y 的最新版本,将其提交到托管 X 的存储库,随着时间的推移,我可能会在本地存储库中对 Y 进行更改。两个月后,我决定将开源 repo 中的最新更改合并回我的,以获取最新的错误修复、功能等。如果这两个分支是同一个 repo 的一部分,那么这将是不费吹灰之力.我怎样才能[相对]轻松地在 Git、Mercurial 和 Subversion 中进行这种跨存储库合并?

谢谢。

【问题讨论】:

    标签: git svn version-control mercurial merge


    【解决方案1】:

    你是说你会在你的存储库中为 X 放一份 Y 的副本吗?如果是这样,那对于您提到的任何 VCS 来说都不是正确的方法。您想将 Y 的存储库“分叉”到 Y-mine 中,并在其中提交您的更改。然后,您在项目 X 中的 构建系统 的配置文件包含一个指向存储库 Y-mine 中特定修订版的指针作为依赖项——任何现代构建系统都会这样做。

    这为您提供了两全其美的优势 - 您可以随时从 Y 合并到 Y-mine,并且您可以将确切版本的 Y-mine 存储在 X 中,以实现 100% 可重现的构建。

    Git 和 Mercurial 都有 subrepo 系统,允许您说“版本 Z 的 Y-mine 是 repo X 的一部分”,但它们比让 pip 或 maven 或 sbt 或 gem 或 visual studio 或 ivy2 或其他任何东西更笨拙...处理依赖管理。

    【讨论】:

    • 你一次又一次地忽略奥卡姆剃刀。 没有新实体,没有额外的层将是更好的起点
    • 我并不是在建议一个“新实体”,只是选择正确的实体。 Python、Ruby、Go、Node 和 Perl 都已经在已经使用的包管理器中内置了 repos-as-dependencies。在 Java 或 C# 环境中,使用 maven 或已经处理此问题的 IDE。我的意思不是试图用 VCS 做包管理器已经做的事情。
    【解决方案2】:

    我的看法是,您可以看看 Debian 使用 git-buildpackage tool 的 Git 打包工作流程做了什么。

    此工具提供的工作流程与上游供应商使用的 VCS 无关,其组织方式(大致)如下:

    • 您有(至少)两个分支:upstreammaster
    • upstream 保存(未修改的)上游源的快照,这些源通常取自上游供应商提供的发布 tarball。也就是说,此分支上的每次提交都来自以下步骤:

      1. upstream 分支已签出。
      2. 删除所有现有文件 (git rm -rf .)。
      3. 新版本的上游源被解包并复制到工作树中,然后添加 (git add .)。
      4. 然后记录一个新的提交(并创建一个标签upstream/vX.Y.Z 指向这个提交)。
    • master 包含 upstream 上的内容以及一组提供构建 Debian 软件包的基础设施的文件(实际上,这只是一个名为“debian”的目录)。

      每次将上游源的新版本导入upstream 分支时,该分支都会合并到master,然后包维护者会着手调整其“debianization”以匹配上游引入的更改。

    我认为这种方法很可能在您使用普通 Git 的情况下使用:

    • 维护这样一个“上游”分支(您可以称其为“供应商”或“that_framework”等)。它应该只接收上游源的新版本(也可能是偶尔的上游补丁等)。
    • 将上游源的新版本导入该分支后,将其合并到您的 master(或任何更适合您的工作流程的分支)。

    使用 Mercurial 和 Subversion 也可以使用它们各自的 Git 垫片来完成,但我怀疑(虽然不确定)这会使事情复杂化,而不是简化。

    【讨论】:

    • 有趣。即使上游库的旧版本不断被删除并被新版本替换,我不确定这是否真的会阻止 repo 大小随着时间的推移而膨胀。此外,我不确定缺少变更集历史记录会如何影响合并。这两个问题可能完全无效,如果有更多版本管理知识的人愿意分享,我很想知道答案......
    • @Ash, 1) Git 只关心它跟踪的文件的内容,所以如果有人像我所描述的那样在新版本的git rm -rf . + git add .实际更改的文件将构成大小增加。这种处理新的上游版本的“奇怪”方式只需要确保上游在旧版本和新版本之间删除的所有文件也从我们三个中删除。
    • @Ash, 2) 虽然我不会发誓,但我认为使用 Git,变更集的历史不会影响合并:在执行典型的三向合并时,Git 只使用历史记录用于定位所谓的“合并基础”——合并双方之间的最后一次共同提交。如果找到此合并基础,则三向合并按原样继续,仅使用这三个提交,否则将降级为仅使用两个提交的简单合并。不会发生复杂的“补丁计算”(a-la Darcs)。
    猜你喜欢
    • 2011-12-05
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 2015-10-13
    • 2021-11-18
    • 2021-09-09
    相关资源
    最近更新 更多