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

9
所以,我已经熟悉这个:
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(与 current 相同)
现在,假设你有两个版本的自己的 'calc' 应用程序:
calc(这基本上是 trunk == calc 2.0) calc-1.0(发布给公众)
假设 calc-1.0 使用 libcomplex 1.0,而 calc(在 trunk 中)使用正在开发的 libcomplex 1.1。 libcomplex 1.0 中有一个 bug,发布了一个新版本来修复该 bug:libcomplex 1.0.1。libcomplex 维护者还将此 bug 修复内容包含在 libcomplex 1.1 中。
你还没有准备好发布 calc 2.0,因此需要将 libcomplex 1.0.1 集成到你的供应商分支中,然后更新 calc-1.0 以发布 bug 修复版本。
它应该放在哪里?
你不能将其放在 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 中。
3个回答

3
推荐的做法是创建一个分支来发布你的版本。这样,无论你在主干上对供应商文件夹做了什么更改,都不会有影响。然后,你可以使用libcomplex 1.0.1更新1.0版本的分支,而这并不会影响主干(calc 2.0)。
但是,如果calc 1.0和calc 2.0在同一个分支中并存,则此方法不适用。
接下来要做的是不要设置“current”。直接引用你正在使用的版本即可。例如,将你的文件夹结构保留为:
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)。它们允许您混合和匹配版本,因此您可以在旧版 libcomplex 的基础上创建代表 Calc 1.0 补丁发布的标签。


在我的先前的示例中,我有一个用于发布calc 1.0的分支。vendor文件夹不包含在calc下面。您是在建议将/vendor也作为分支吗?为了清楚起见,这是我所描述的示例:/vendor/libcomplex/ /calc/trunk/ /calc/branches/1.0/您建议不使用“current”,只使用文件夹结构将无法正确地允许将更改合并到主干版本中,从而达不到目的。您需要此更改历史记录以允许将更改合并到主干中,其中您已修改了原始供应商源。 - Amir Ebrahimi
我的方法适用于仅使用发布版本的情况。如果您还要修改源代码,则将供应商代码视为自己的代码可能很有用(即将其包含在主干分支中,而不是将供应商作为单独的文件夹)。但是您的方法也很有道理。创建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。 - Nader Shirazie

2

我在使用外部库时,通常会按照以下方式进行操作:

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>从不更改,并且使用svn cp vendor/<lib>/<version> mypatched-vendor/<lib>/<version>启动mypatched-vendor。

现在对比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

当我想测试一个新的库版本时,我只需将属性编辑到另一个地方并运行更新。这也有助于防止我意外提交任何对树中libcomplex部分的更改,即使我在WC上更改了一些文件。我必须在该目录下或特别提交更改。

现在,我的项目升级、修复和分支可以轻松地移动到新的libcomplex版本,而不需要进行更多的初始合并到mypathed-vendor。所有我的项目分支只需要propchange和测试。此外,在我看来,获取我的项目的库依赖关系也相对容易。

关于externals的最后一个好处是,当开始一个新项目并且上游也在大量开发并使用svn时,如果您不需要对该库进行补丁,可以将上游作为external引用。当上游破坏您的项目时,您可以使用-rNUM选项暂时保留上游版本,例如:

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

svn:externals 的一个明显缺点是,外部 url 必须能够在项目的所有检出变体中使用相同的 URI 访问。

但是,使用 externals 可以将 vendor 存储库与 project 存储库分开。


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,然后像往常一样将其标记并复制到我们自己的树中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接