Posted on 2014-01-13 16:47
魔のkyo 阅读(1352)
评论(0) 编辑 收藏 引用
如何维护共享代码,和项目SVN仓库的结构有关,一般有以下两种结构:
一种结构是公司(或部门)的所有项目,或者一系列相关项目建立在一个SVN仓库下
repository
├─branches
├─tags
└─trunk
├─commonlibs
│ ├─commonlib1
│ └─commonlib2
├─project1
└─project2
这种结构下共享公共代码的方式是很显然的,只要将公共代码提出到commonlibs中。
但这种方式有几个缺点,签出项目要么签出所有项目的代码,要么分别签出需要的库和项目代码,签出所有代码是不合适的,除非是一个开发团队负责这一系列项目的情况。一方面是访问权限没有得到控制,另一方面你不得不在每次update时得到其他所有和你的项目不相干的更新。所以应该分别签出需要的库和项目代码。但是无论如何在创建branch或tag的时候你必须创建所有代码的branch或tag,而不是单独按项目创建。另外如果每个项目希望使用不同版本的共享代码时会遇到麻烦,如果我们把commonlibs创建不同的分支给不同的项目使用,在每个项目的工作目录下会是这样的结构
workdir
├─project1 <= repository/trunk/project1
└─commonlibs <= repository/branches/versionxxx/commonlibs/
这时仓库并没有帮你记录某个版本的project1需要使用什么路径什么版本的commonlibs,你必须额外自己记录,例如在project1的目录下创建一个批处理来取得正确版本的commonlibs,因为你还要考虑到创建分支或者标记tag也必须记录正确的commonlibs版本。
另一种结构是公司(或部门)的每个项目都有独立的SVN仓库(其实我比较推荐这种方式)
repository1
├─branches
├─tags
└─trunk
├─commonlib1
├─commonlib2
└─project1
repository2
├─branches
├─tags
└─trunk
├─commonlib1
├─commonlib2
└─project2
我们可以看到,如果将公共库放在项目中管理那么代码其实并没有共享,所以我们还需要一个共享代码的仓库,然后在项目的仓库中通过svn提供的externals属性指定外部代码。
repository_commonlibs
├─branches
├─tags
└─trunk
├─commonlib1
└─commonlib2
repository1
├─branches
├─tags
└─trunk
├─commonlib1 <= (svn:externals repository_commonlibs/trunk/commonlib1)
├─commonlib2 <= (svn:externals repository_commonlibs/trunk/commonlib2)
└─project1
repository2
├─branches
├─tags
└─trunk
├─commonlib1 <= (svn:externals repository_commonlibs/trunk/commonlib1)
├─commonlib2 <= (svn:externals repository_commonlibs/trunk/commonlib2)
└─project2
需要注意的是在我使用的svn版本中externals属性其实是指定在外部代码文件夹的上级目录,这里也就是trunk。还有,在文件夹update时会连带更新其中的外部代码文件夹,而commit时需要单独提交。
另外如果每个项目希望使用不同版本的共享代码,我们可以在共享代码仓库上新建分支,然后不同项目指定不同的externals路径即可。
repository_commonlibs
├─branches
│ ├─project1
│ │ ├─commonlib1
│ │ └─commonlib2
│ └─project2
│ ├─commonlib1
│ └─commonlib2
├─tags
└─trunk
├─commonlib1
└─commonlib2
此外,通过externals指定的目录在project使用TSVN创建分支时还会提示是否需要关联确切的外部库版本信息。
参考:版本控制之道——使用Subversion,第二版 P140-P145