SVN和代码在多个项目之间共享
我在 SVN 中有多个项目。这些项目中的每一个都位于其自己的主干中,并进行分支以进行发布。
并且有一个在每个项目中使用的共享代码。问题是处理代码的最佳方法是什么。
让我给出几个场景以及与之相关的问题
a) 将共享代码放在单独的主干(或存储库)中并使用 svn:external。
如果我们对某些项目进行分支,则会出现两个问题:
- 在主干中对共享代码进行的任何修改都会传播到分支,因为 svn:external 会拾取更改
- 如果我们需要在某些情况下当返回并准确构建为发布而构建的代码时,我们将很难获得准确的代码,因为 sNV:external 将再次获取共享代码的最新副本,而不是项目分支时的代码。
据我了解,有一种解决方法。一旦我们分支,我们就可以修改 svn:external 以获取共享代码的精确版本。然而,又存在两个陷阱:
- 您需要记住每次分支时都执行此操作。 (我讨厌这样的事情,很容易忘记)。
- 如果您需要对分支/发布的项目进行修补程序,则无法修改共享代码。
b) 另一种解决方案是在项目分支时分支共享代码,并将 external 更改为指向共享代码的分支副本。
- 同样,问题之一是手动步骤,这很容易忘记
- 另一个问题是合并问题。当您尝试将项目中的更改合并到主干时,SVN 将跳过外部。因此,开发人员再次需要记住手动合并共享代码。
我错过了什么吗?有什么合理的方法来处理这个问题吗?
I have multiple projects in SVN. Each of these project sits in it's own trunk and branched for releases.
And there is a shared code which is used in each project. The question is what is the best way to handle the code.
Let me give couple of scenarios and the issues related to them
a) Put the shared code in separate trunk (or repository) and use svn:external.
In the case if we branched some of projects, there will be two problems:
- Any modification of shared code which are made in trunk will be propagated to branch, because svn:external will pick up the changes
- In the case if we will need at some moment go back and build exactly the code which was build for release, it will be hard for us to get exact code, because snv:external will again pick up latest copy of shared code, instead of code at the moment when project was brached.
As I understand there is one work around. As soon as we branch, we can modify svn:external to pick up exact revision of shared code. However, there are again two pitfalls:
- You need remember to do this each time when you branch. (I hate such things, which is easy to forget).
- You can't modify shared code, if you need to do a hotfix for the branched/released project.
b) Another solution is to branch shared code when the project is branched and change external to point to bracnhed copy of shared code.
- Again, one of the problem is manual step, which is easy to forget
- Another problem is merge problems. SVN will skip externals when you will try to merge changes in the project to the trunk. So, again, developer needs to remember to merge shared code manually.
Am I missing anything? Is there any reasonable way to handle this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
就我个人而言,我保留一个单独的存储库,然后使用 [http://svnbook.red-bean .com/en/1.0/ch07s03.html svn:externals] 属性。
SVN 外部允许您链接到其他存储库(甚至是您不运行的存储库,例如 smarty subversion 存储库),当您运行 svn update 时,您的项目和外部存储库都将更新。
使用 SVN 外部,您还可以使用
http://path-to-project.com/svn/thing -r1234
等链接到特定修订版本,以获取发布和其他需要保持静态的内容最佳实践恕我直言,始终指定修订版,然后在对共享库进行更改时更新修订版号,以便您可以跟踪更新此数据的原因。当您标记或分支主项目时,还可以保持一切正常。
Personally i keep a separate repository then use the [http://svnbook.red-bean.com/en/1.0/ch07s03.html svn:externals] attribute.
SVN Externals allow for you to link to other repositories (even ones you dont run e.g. the smarty subversion repo) when you run an svn update both your project and the external repo will be updated.
with SVN externals you can also link to specific revisions using somethign like
http://path-to-project.com/svn/thing -r1234
for releases and other things that you need to keep staticBest practice IMHO is to always specify a revision then update the revision number as you make changes to the shared library so that you can keep track of WHY you updated this data. also keeps everything sane when you tag or branch the main project.
您有两个正确答案,但有两组缺点。
这是我的建议
将您的共享代码放入另一个存储库中,
用发布版本标记代码
在你的 trunk 目录中创建一个指向你的标签的 svn externals。
当您更改库时,重新标记它并更新您的主干应用程序。
当您选择分支时,您的分支仍将指向库的正确标记版本。
或者,尝试构建库的单独版本,并将该库作为 jar 或 lib/so 引用。
You have two correct answers, with two sets of drawbacks.
Here's what I would recommend
Put your shared code into another repository,
tag the code with the release version
Create an svn externals in your trunk directory that points to your tag.
When you change your library, retag it, and update your trunk application.
When you take a branch, your branch will still point to the correct tagged version of your library.
Alternatively try building a separate release of your library, and reference the library as a jar or lib/so.
我们使用类似于 CWT 的系统:共享代码本身往往是单独的项目,因此单独存在于存储库(或单独的存储库)中。在使用外部项目(上游项目)的项目中,我们包含共享/下游项目的编译/打包二进制文件。
这样上游项目就不会因为下游项目的意外变化而受到影响。
我们编写了一些脚本,以便在必要时使用这些二进制文件的较新版本自动更新主要上游项目(否则,将包复制到适当的项目中是一个手动过程,但这并不是什么大不了的事情)。
到目前为止,我们在这种 madnes^W 方法中看到的缺点是,正在进行非常积极开发的下游项目(例如,在新库的早期阶段)需要看似过多的更新上游项目。测试上游项目可能需要更新共享库、编译、复制上游二进制文件以及编译/部署/任何上游项目。然而,一旦库的最初疯狂开发减慢并且库变得有些稳定,这个“问题”就消失了。
与 CWT 一样,上游项目无法以任何有意义的方式修改共享代码。必须在该项目中明确地向下游进行更改,并在必要时向上游传播。
We use a system similar to CWT's: Shared code tend to be separate projects in their own right, and as such exist separately in the repository (or a separate repository). Within the project that uses the external projects (the upstream project), we include the compiled/packaged binaries for the shared/downstream project.
This way the upstream project won't be sniped by unexpected changes in downstream projects.
We've written some scripts to automatically update the major upstream projects with newer versions of these binaries when necessary (otherwise it's a manual process to copy the package into the appropriate projects, but that's not that big of a deal anyway).
The drawback we've see so far in this madnes^W method is that downstream projects undergoing very active development (say, in the early stages of a new library) require what may seem like an excessive number of updates to the upstream project. Testing the upstream project can require updating the shared lib, compiling, copying that binary upstream, and the compiling/deploying/whatever the upstream project. However, once an initial frenzy of development on a library slows and the lib becomes somewhat stable, this "problem" evaporates.
As with CWT, the upstream project can't modify the shared code in any meaningful way. Changes downstream must be made within that project explicitly, and propagated upstream where necessary.
我们使用如下所示的单个存储库结构:
在 C#(可能不是您选择的语言)中,project1 和 project2 包含对 classlibrary 的引用。当我们构建时(这是已编译的 .NET 模型的一大优势),正在构建的项目和 class_library 之间的任何不一致都会被发现。这些不一致在提交更改之前得到解决。使用基于服务器的构建工具(我们使用 CruiseControl.NET),我们可以同时构建所有项目,这将告诉我们任何问题。
除非您的project1和project2需要引用特定版本的classlibrary(我们避免这样做,试图使project1和project2始终使用class_library的最新版本),否则这工作得非常顺利。
我倾向于避免为相关应用程序创建单独的存储库。由于上面示例中的 class_library 将所有这些东西联系在一起,因此在单独的版本中维护它几乎没有优势或逻辑,因为它在项目级别分离的真正原因是它是共享代码。共享代码的生产应用程序这样做是有原因的 - 它们应该使用相同版本的共享代码,这意味着它们应该属于同一源代码控制分支。
We use a single repository structure like this:
In C# (which may not be your language of choice), project1 and project2 include a reference to classlibrary. When we build (here's a great advantage of the compiled .NET model), any inconsistencies between the project being built and class_library are found. These inconsistencies are resolved before committing changes. Using a server-based build tool (we use CruiseControl.NET) we can build all of the projects simultaneously which will tell us of any problems.
Unless your project1 and project2 need to reference a specific version of classlibrary (which we avoid, trying to make project1 and project2 always use the latest rev of class_library), this works incredibly smoothly.
I tend to avoid making separate repositories for related applications. Since the class_library in the above example ties all of these things together, there is little advantage or logic in maintaining it in separate versions since the real reason that it is separated at the project level is that it is shared code. Production apps that share code do so for a reason - they should be using the same version of the shared code, which implies that they should be part of the same source control branch.
我对处理共享代码(特别是使用 Java 和 .NET 或 C/C++ 库)的建议是使用两组存储库:一组用于源代码,另一组用于版本控制已发布的映像。当您对“通用”项目进行更改时,您将源代码更改提交到源代码树,然后构建它,然后通过将二进制文件作为新修订版提交到发布树上来发布二进制文件。使用“common”项目的项目然后使用 svn:externals 属性来引入已发布的二进制文件。没有诱惑去修改共享代码的本地映像。如果有人想要修改“通用”代码,那么他们可以通过该项目的正常开发实践来完成。
有关更多详细信息,请参阅此 回答类似的问题。
My recommendation for handling shared code (particularly with Java and .NET or a C/C++ library) is to use two sets of repositories: one for source code, and another for versioning released images. When you make changes to the 'common' project, you commit your source changes to the source tree, then build it and then publish the binaries by committing them as a new revision on the release tree. The projects that use the 'common' project then use the svn:externals property to bring in the released binaries. There's no temptation to modify the local images of the shared code. If someone wants to modify the 'common' code, then they do that through the normal development practices for that project.
For more details, see this answer to a similar question.
您的列表中缺少的答案是:
c) 始终将外部指向共享代码的特定版本。
这非常有效:
如果需要,可以在单独的工作副本中签出库并与主项目一起进行修改。如果临时更改项目以从磁盘上的工作副本获取代码,则您仍然可以在需要时并行处理库和项目。
The answer that's missing from your list is:
c) Always point externals to a specific version of the shared code.
This works remarkably well:
If required, libraries can be checked out in a separate working copy and modified alongside your main project. If the project is temporarily changed to pick up code from the working copy on disk, you can then still work on libraries and projects in parallel, if needed.