在 SVN 中处理供应商分支的最佳方法是啥?

Posted

技术标签:

【中文标题】在 SVN 中处理供应商分支的最佳方法是啥?【英文标题】:What is the best way to handle branches of vendor branches in SVN?在 SVN 中处理供应商分支的最佳方法是什么? 【发布时间】:2010-11-19 20:06:32 【问题描述】:

所以,我已经很熟悉了: http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html

我的问题是,您如何处理同时具有稳定版本和要集成的 alpha/beta 分支的供应商分支?

因此,假设您遵循 SVN 书中的原始示例。你会有:

svn://localhost/home/svn/vendor/libcomplex/current svn://localhost/home/svn/vendor/libcomplex/1.0 svn://localhost/home/svn/vendor/libcomplex/1.1(与当前相同)

现在,假设您有两个版本的“计算”应用:

calc(这本质上是trunk == calc 2.0) calc-1.0(公开发布)

假设 calc-1.0 使用 libcomplex 1.0,而 calc(在主干中)使用仍在开发中的 libcomplex 1.1。

libcomplex 1.0 中存在一个错误,并且发布了一个新版本来修复该错误:libcomplex 1.0.1。 libcomplex 维护者也将此错误修复包含在 libcomplex 1.1 中。

您还没有准备好发布 calc 2.0,因此您需要将 libcomplex 1.0.1 集成到您的供应商分支中,然后更新 calc-1.0 以进行错误修复发布。

它去哪儿了?

你不能把它放在 svn://localhost/home/svn/vendor/libcomplex/current 因为目前有 1.1。

您是否将 svn://localhost/home/svn/vendor/libcomplex/1.0 复制到 svn://localhost/home/svn/vendor/libcomplex/1.0.1 然后引入新版本?这样你就可以使用 svn 将 1.0 和 1.0.1 之间的差异合并到 calc-1.0。

【问题讨论】:

【参考方案1】:

我使用外部库是这样工作的:

project/myProject/branches,trunk
vendor/libcomplex/1.0 
vendor/libcomplex/1.0.1
vendor/libcomplex/2.0.0
mypatched-vendor/libcomplex/1.0
mypatched-vendor/libcomplex/1.0.1
mypatched-vendor/libcomplex/2.0.0

其中vendor/<lib>/<version> 在导入后永远不会更改,mypatched-vendor 以svn cp vendor/<lib>/<version> mypatched-vendor/<lib>/<version> 开头。

现在 diffing vendor/libcomplex/1.0 mypatched-vendor/libcomplex/1.0 应该会为您提供要合并到刚刚导入的 1.0.1 版本的补丁。

我可能是少数,但我喜欢svn:externals 属性。相当多的 IDE 不喜欢它们,因此请谨慎使用。原因是这样的。我现在可以编辑我的主项目了:

checkout project/myProject/trunk to myprj-trunk 签出运行。

svn propedit svn:externals .
# with
libcomplex  URLTO/mypatched-vendor/libcomplex/1.0

当我想测试一个新的 lib 版本时,我只需将该属性编辑到另一个位置并运行更新。这也有这样的效果,即使我在 WC 上更改了一些文件,我也不会意外地向树的 libcomplex 部分提交任何内容。我必须在该目录下或专门在那里提交更改。

现在,我的项目的升级、修复、分支可以轻松移动到新的 libcomplex 版本,而无需最初合并到 mypathed-vendor。我所有的项目分支只需要 propchange 和测试。恕我直言,为我的项目获取库依赖项也相对容易。

关于 externals 的最后一个好处是,当开始一个新项目时,upstream 也被大量开发并使用 svn,如果您不需要修补该库,您可以将 upstream 作为外部引用。当上游中断您的项目时,您可以使用 -rNUM 选项将上游版本保留一段时间,例如:

libcomplex -r21 UPSTREAMURLTO/mypatched-vendor/libcomplex/trunk

svn:externals 的一个明显缺点是外部 URL 必须可以从项目的所有结帐变体中使用相同的 URI 访问。

但是使用外部可以让您将 vendor 存储库与您的 项目 存储库分开。

【讨论】:

【参考方案2】:

供应商分支背后的想法似乎是它们应该反映供应商自己的存储库的样子。所以,current 代表厂商的主干,标记的版本代表厂商自己的标签,在每个版本发布时创建。

鉴于此,问题的答案变得相当清楚。为了发布 1.0、1.1 和 1.0.1,供应商大概有一个 1.0.x 错误修复版本的分支,同时继续在他们的主干上处理 1.1 和更高版本。我们的供应商分支应反映此设置。

也就是说,我们还需要一个分支(在我们的供应商分支内)用于 1.0.x 错误修复版本。这应该是在它包含 1.0 时从当前创建的,并且可以命名为 current-1.0.x 之类的名称。然后可以更新此分支以保存 1.0.1,然后可以像往常一样标记并复制到我们自己的树中。

【讨论】:

【参考方案3】:

推荐的做法是为您的版本创建一个分支。这样,您在主干中对供应商文件夹进行的更改都无关紧要。然后,您可以使用 1.0.1 版本的 libcomplex 更新 1.0 发布分支,这不会影响主干(计算 2.0)。

但是,如果 calc 1.0 和 calc 2.0 在同一个分支中并存,这将不起作用。

接下来要做的是没有“当前”。直接参考您使用的版本即可。例如,将您的文件夹结构保留为:

vendor/libcomplex/1.0
vendor/libcomplex/1.1
vendor/libcomplex/1.0.1

永远不要覆盖这些文件。那么calc 2.0可以参考libcomplex 1.1版本,calc 1.0可以参考1.0.1。

你的最后一个选择,(并不是真的推荐)是使用 svn 标签(见complex tags)。它们允许您混合和匹配版本,因此您可以在技术上创建一个标签来表示您的 calc 1.0 的补丁版本与旧版本的 libcomplex。

【讨论】:

在我之前的示例中,我的版本确实有一个分支:calc 1.0。供应商文件夹不包含在 calc 下。您是否建议 /vendor 也被分支?这里要清楚的是我正在描述的示例: /vendor/libcomplex/ /calc/trunk/ /calc/branches/1.0/ 您不使用“当前”而仅使用文件夹结构的建议将无法正确允许合并在版本之间更改为主干,从而达到目的。您需要此更改历史记录以允许将更改合并到您已修改原始供应商源的主干中。 我的方法适用于您所做的一切都是使用已发布版本的作品。如果您还修改了源代码,那么将供应商代码视为您自己的代码可能很有用(即,将其包含在您的主干分支中,而不是将供应商作为单独的文件夹)。但是,您的方法也很有意义。创建 vendor/libcomplex/1.0.1 分支,合并任何自定义,并更新 calc 1.0 版本以指向 vendor/libcomplex/1.0.1,然后发布 calc 1.0.1。每当 libcomplex 1.1 准备好时,合并定制,构建 calc2.0,你就可以开始了。主干从不指向 1.0.1

以上是关于在 SVN 中处理供应商分支的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

从 .CSV 文件比较/插入/更新 MySQL 数据库中的产品的最佳方法是啥

处理监视器警报过载和脱敏的最佳方法?

如何清理 CVS 供应商分支导入?

供应商在 Web 文件结构中的含义是啥?

供应商文件夹中的 symfony 是啥?

SVN分支/合并原理及最佳实践