nix操作系统中有link链接文件类型,硬链接(hard link)和符号链接(symbolic link)两种形式,硬链接只能在同一个分区内对文件使用,使用起来感觉就像是为文件创建了一份同步更新的副本,命令:ln link_target link_filename;符号链接则可用于文件和目录,纯粹就是一个指向链接目标的“指针”而已,并没有真正把内容复制过来,命令:ln -s link_target link_filename。实际应用中我个人的感觉是符号链接使用得更多一些,两种链接都比windows下的“快捷方式”要强大得多。
那么在svn的应用当中,如果两个项目共用一个库文件,使用符号链接文件就不需要两边分别更新了,不是很方便么?但是今天在一个项目中试用了一下,却不是我想像的那样。
我的情况是这样的,本来的项目中有一个dbupdater.php,现在转移到另外一个项目中了,但是在这个项目中还要继续使用,就产生了我刚才说的需要两边更新的问题,so想着采用link的方式,直接删除掉dbupdater.php,并创建了一个同名的符号链接文件覆盖了它,结果在svn commit的时候就出错了:
原来,svn不仅跟踪记录了文件内容,连文件类型也记录了(nix下文件分为三种类型:file, dir, link),这样直接替换是不行的。如果硬是要用链接文件替代正常的文件,只有一种办法:先用svn rm删除掉原来的文件,提交,再用svn add添加链接文件,提交。不仅如此,我还测试了一下,发现这样提交到svn服务器上的文件内容居然是:
也就是说,使用了符号链接之后,提交到服务器上去的并不是链接指向文件的内容,而是符号链接的“符号”而已,这样,如果在另外一台不同环境的客户端checkout出来,符号链接文件也许就不能正常工作了。
所以,虽然svn支持link类型的文件,但除了在少数情况下可以使用hard link,或者在项目内部文件之间使用symbolic link之外,尽量不要link项目之外的文件,因为结果并非我们所期待的那样。
参考: Problem replacing symbolic links Basic question ->Re: Basic question
另外再搭车介绍一下svn的“廉价复制”功能,svn创建tag或branch的机制和cvs不同,他基本上是通过创建一份拷贝的方式来创建tag或branch的,不过你不用担心这样会占用成倍的空间,因为svn的拷贝是一种“廉价复制”,只有当tag或branch中的文件被修改时才会真正的另存一份,这也是svn和cvs的一个主要区别,延伸阅读。
PS: 现在海缆断了,查点资料那叫费劲啊,我容易么我?可spam怎么还是那么多呢?
你好!看了你的文章很受用,谢谢.我最近刚刚开始接触了SVN的东西,有很多地方不清楚,正在努力学习中.希望可以经常交流. ^_^
没问题 🙂
有一种办法可以实现符号链接的效果:组合的svn co。
比如一段公共的代码在src/com/xxx/comm/ 然后两个项目src/com/xxx/p1和src/com/xxx/p2。那么可以
svn co svn://HOTNAME/PATH/src/com/xxx/p1 /your/path/p1/src/com/xxx/p1 svn co svn://HOTNAME/PATH/src/com/xxx/comm/ /your/path/p1/src/com/xxx/comm/
这样对你的IDE等工具看起来是一个文件夹,然是实际上来此多个地方。
其实还是分别co到不同的子目录,对吧。
现在的项目中我的看法是,能外部引用的就外部引用, 放到include_path里,或者使用从/开始的地址,比如/lib, link在svn里几乎不用,也尽量不用。
好像只有一种方法可以用,那就是项目内部采用相对地址的link。