公司中特定的颠覆回购布局
首先我将解释一下我们公司使用 Subversion 的一些历史。 我们大约 3 年前开始使用 Subversion。我们将它与 TortoiseSVN 作为客户端一起使用。
我们有 3 个存储库,它们的项目完全不同,没有任何共同点。
但在 1 个存储库中,我们大约有 6 个产品/项目共享通用 dll(用于压缩、xml、基本类型等) 我们有大约 20 个这样的常见 dll(仍在更新中)。
所以这20个Common Dll和需要它们的6个项目一起在主干中。
现在后备箱确实被填满了,其缺点是所有项目都相互依赖。因此,如果在一个项目的 1 个公共 dll 中进行更改,那么所有其他项目都需要更新,并且需要进行调整和验证。
由于这不太方便(特别是当您想要发布一个产品,然后其他产品出现一些新的更改时),我们认为将每个项目的所有内容拼接起来。仍然保留大主干以在不同项目之间同步。
因此,我们为每个项目创建 trunk/branches/tags 文件夹,并仅对该项目所需的 dll 进行 svn 复制。
情况:
之前:
-branches
-tags
-trunk
-Common DLL 1
-Common DLL 2
-Common DLL 3
-Common DLL 4
-Common DLL 5
-Project 1
-Project 2
-Project 3
现在
-Projects
-Project1
-branches
-tags
-trunk
-Common DLL 1
-Common DLL 2
-Project1
-Project2
-branches
-tags
-trunk
-Common DLL 2
-Common DLL 3
-Common DLL 4
-Project2
这种方法的优点是您可以更好地了解不同项目拥有哪些 dll,并且可以将每个单独的项目作为完全递归而不是部分结账。 当我们同步公共 dll 时(对于发布很重要),我们也有更多的控制权,并且我们没有其他项目开发人员提交的未完成的工作。
然而:我们在合并这些 Common Dll 时确实遇到了很多问题。使用(最新的)TortoiseSVN,我们不断地遇到“树冲突”。还有很多合并问题(有时回溯一个多月而不记得真正改变了什么)。
另外,重命名 dll 也会出错,Tortoise 总是将项目中尚未包含的所有 trunk dll 添加到该项目的工作副本中。然后你总是必须在签入之前手动删除这些。
我知道我们永远不应该使用“重新集成分支”,但还有两个选择。有人知道哪一个最好吗?
我们可以保留这个回购结构还是应该改变它。 将所有 Common Dll 放在另一个 Repo 中然后使用外部是否更好?
谢谢
First I'll explain some history of using Subversion in our Company.
We started using Subversion around 3 years ago. We use it with TortoiseSVN as Client.
We have 3 repositories with totally different projects who don't have anything in common.
But in 1 repository we have about six products/projects who share common dll (for zipping, xml, basetypes, etc)
We have around 20 of these common dll (who are still being updated).
So these 20 Common Dll are in the trunk together with the six projects who need them.
Now the trunk is really getting filled and the drawback of these is that all projects rely on each other. So if changes are done in 1 common dll for one project, then all other projects need to update and need to be adapted and validated .
Since this is not that handy (specially when you want to release a product and then some new changes come in from other products) we thought to splice up everything per project. Still keeping the big trunk to synchronize between the different projects.
So we create trunk/branches/tags folder per project and do a svn copy of only the dll needed for that project.
Situation:
Before:
-branches
-tags
-trunk
-Common DLL 1
-Common DLL 2
-Common DLL 3
-Common DLL 4
-Common DLL 5
-Project 1
-Project 2
-Project 3
Now
-Projects
-Project1
-branches
-tags
-trunk
-Common DLL 1
-Common DLL 2
-Project1
-Project2
-branches
-tags
-trunk
-Common DLL 2
-Common DLL 3
-Common DLL 4
-Project2
The advantage of this approach is that you have better overview what dll the different projects have and you can check out each separate project as Fully recursive in stead of partial checkout.
We also have more control in when we do the synchronisation of the common dll (important for releases) and we don't have unfinished work commits from other project developers.
HOWEVER: we do have a lot of problems merging these Common Dll. With (latest) TortoiseSVN we have constantly "tree conflicts". Also a lot of merging problems (sometimes going back for more than a month and not remembering what really changed).
Also renaming dll goes wrong and Tortoise always add all the trunk dll not yet in the project to the working copy of this project. Then you always have to manually delete these before checking in.
I know we should never use "Reintegrate a branch", but there are two options left. Anyone knows which one is best?
Can we keep up this repo structure or should we change it.
Is it better to put all Common Dll in another Repo and then using externals?
thx
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
不一定是“另一个仓库”,但你绝对应该将其视为一个独立的项目。您的布局应如下所示:
然后
Project1/trunk
可能会有一个svn:externals
属性,其内容如下:此属性使 subversion 自动创建文件夹
CommonDLL1每当您进行签出或更新时,
和CommonDLL2
都位于Project1/trunk
的工作副本中。请注意外部定义如何包含修订号。这可以确保如果您更改 CommonDLL1 中的某些内容,则不会影响
Project1
,除非您显式更改外部定义中的修订号。这对于项目标签的不变性尤其重要。这种方法有一些缺点,您必须权衡其优点:
如果您通过
Project1
的工作副本提交来对CommonDLL1
进行更改,那么您当更新后更改神秘消失时,您可能会感到困惑。这是因为 SVN 不会自动调整外部定义中的修订号。您必须显式更改它并提交该更改。让您的团队了解这一点。您的持续集成服务器不会自动发现最新的
Project1/trunk
不再针对最新的CommonDLL1/trunk
进行构建。只有当您更改外部定义中的修订号时,您才会发现这一点。Not necessarily "another repo", but you should definitely treat it as a project that stands on its own. Your layout should look like this:
Then
Project1/trunk
would probably have asvn:externals
property with this content:This property causes subversion to automatically create the folders
CommonDLL1
andCommonDLL2
inside your working copy ofProject1/trunk
whenever you do a checkout or update.Note how the externals definition contains a revision number. This ensures that if you change something in CommonDLL1, this will not affect
Project1
until you explicitly change the revision number in the externals definition. This is especially important for the immutability of your project tags.There are some downsides to this approach which you have to weigh against the upsides:
If you make a change to
CommonDLL1
by committing via a working copy ofProject1
, you might be confused when the change mysteriously disappears after an update. This is because SVN will not automatically adjust the revision number in the externals definition. You have to explicitly change it and commit that change also. Educate your team about this.Your continuous integration server will not automatically discover that the latest
Project1/trunk
no longer builds against the latestCommonDLL1/trunk
. You will only find out about that when you change the revision number in the externals definition.趋势是将事物分成(合理的)逻辑的、独立的单元。有趣的是,Git DVCS 提高了人们的意识:想要仅签出 /trunk/project 的人们面临着这样做的不可能,并且普遍的反应是将项目(算作独立单元)切分成自己的存储库。
虽然这种细粒度的包(“/project/trunk”方法)需要更多的工作,但每个组件的独立性最终会为人们带来好处。项目/代码的解耦导致人们更多地思考API和交互。换句话说,我们可能不再需要了解整个画面,而能够只专注于少数几个组成部分。
请参阅 Xorg,它采用了这种分割存储库的方案(每个存储库都有自己的主干/主干)。
对您而言,这意味着:您的“现在”状态与此描述非常相符。然而遗憾的是 TSVN 无法处理存储库状态;糟糕的工具交互与 SVN 几年前做出的设计决策相结合。
The tendency is to split things into (sensible) logical, freestanding units. Interestingly, the Git DVCS has increased the awareness: people wanting to checkout just /trunk/project were faced with the impossibility of doing so, and the general response has been to chop up projects (counts as a freestanding unit) into its own repo.
While such finely-grained packages (the "/project/trunk" approach) involves a bit more work, the independence of each component plays out for people in the end. The decoupling of projects/code leads people to think more about APIs and interaction. In other words, it is possible to not need to know of the entire picture anymore and be able to concentrate on a few components only.
See Xorg which employs this scheme of split repositories (in the sense of each having its own master/trunk).
For you that means: Your "now" state matches this very description. It is a pity TSVN can't deal with the repository state however; bad tool interaction combined with the design decisions SVN made a few years ago.
我认为第二种方法比第一种方法要好得多。但一开始就有点难以管理。
I think the second approach is much better than the first one. But little bit hard to manage in the first place.