于是刚才想找办法让这过程更自动化一些。不过发觉TortoiseSVN在无干预命令行批处理方面还是不太适合(毕竟它是个GUI客户端),所以跑到 SVN官网去下载了Subversion 1.4.6,安装。装好之后在命令行试了一下操作,没问题。
接下来就是如何自动化的问题了。我那些版本库不都是在同一嵌套层上的,有的深有的浅。例如说这样:
repository + IronRuby * trunk * Nemerle + Ruby * Ruby_1_8 * trunk
星号标注的是要更新的目标。怎么办呢?只好递归搜索了。反正能找到带有".svn"目录的最上层目录就被认为是版本库目录,以它为标准来判断是不是要更新的目标;如果是目录但不是目标则遍历子目录来寻找目标。
于是简单的写了这样的Ruby脚本:
#!/usr/bin/ruby def update_repo( path ) puts path system "svn up \"#{path}\"" end def locate_and_update( dir = "." ) entries = Dir.entries( dir ).reject do |item| item =~ /^\.(?:\.|git|hg)?$/ # remove ".", "..", ".git", ".hg" end if entries.include? ".svn" # if this is a repo update_repo dir # perform update else # if this isn't a repo entries.each do |e| # recursively search for repos path = "#{dir}/#{e}" locate_and_update path if File.directory? path end end end puts Time.now # show the time of update locate_and_update # start from the working directory
把这个脚本放在我的repository目录里,它就能帮我更新整个目录里所有的SVN版本库。当然,递归搜索的效率不是太好——如果有任何一个目录里没有任何子目录是SVN版本库,这脚本恐怕要花上好长时间才能“知道”这点。要想快点的话可以改进上面的代码,让locate_and_update搜索一个内容是目录索引的配置文件,如果不存在的话就以深度优先搜索创建一个索引。那样就不用每次都对整个repository目录做全面搜索了。如果版本库的数量或者位置发生了改变,只要把那个索引文件删除它就应该重新生成索引,也不费事。
要完善的话还可以加点参数什么的,也可以做非交互式处理(传--non-interactive参数给svn)。不过上面的代码已经足够满足我自己的需求了,我的repository目录里全是SVN版本库,暂时没把git和Mercurial相关的东西放进来……所以懒得多写脚本了 ^ ^