为了争论,假设我正在开发一个项目 X,它有一个依赖项 Y。现在 Y 是一个独立的开源项目,由第三方定期维护和更新。我检查了 Y 的最新版本,将其提交到托管 X 的存储库,随着时间的推移,我可能会在本地存储库中对 Y 进行更改。两个月后,我决定将开源 repo 中的最新更改合并回我的,以获取最新的错误修复、功能等。如果这两个分支是同一个 repo 的一部分,那么这将是不费吹灰之力. 我如何[相对]轻松地在 Git、Mercurial 和 Subversion 中进行这种交叉回购合并?
谢谢。
为了争论,假设我正在开发一个项目 X,它有一个依赖项 Y。现在 Y 是一个独立的开源项目,由第三方定期维护和更新。我检查了 Y 的最新版本,将其提交到托管 X 的存储库,随着时间的推移,我可能会在本地存储库中对 Y 进行更改。两个月后,我决定将开源 repo 中的最新更改合并回我的,以获取最新的错误修复、功能等。如果这两个分支是同一个 repo 的一部分,那么这将是不费吹灰之力. 我如何[相对]轻松地在 Git、Mercurial 和 Subversion 中进行这种交叉回购合并?
谢谢。
你是说你会在你的存储库中为 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 或其他任何东西更笨拙......处理依赖管理。
我对此的看法是,您可以看看Debian使用该git-buildpackage
工具对其 Git 打包工作流程做了什么。
该工具提供的工作流程与上游供应商使用的 VCS 无关,并且(大致)组织如下:
upstream
和master
.upstream
保存(未修改的)上游源的快照,这些源通常取自上游供应商提供的发布 tarball。也就是说,此分支上的每次提交都来自以下步骤:
upstream
分支已签出。git rm -rf .
)。git add .
)。upstream/vX.Y.Z
创建一个指向该提交的标签)。master
包含正在运行的内容upstream
以及一组提供构建 Debian 软件包的基础设施的文件(实际上,这只是一个名为“debian”的目录)。
每次将上游源的新版本导入upstream
分支时,该分支都会合并到master
中,然后包维护者会在 master 上调整其“debianization”以匹配上游引入的更改。
我认为这种方法很可能在您使用普通 Git 的情况下使用:
master
(或任何更适合您的工作流程的分支)。使用 Mercurial 和 Subversion 也可以使用它们各自的 Git 垫片来完成,但我怀疑(虽然不确定)这会使事情复杂化,而不是简化。