34.3 版本库转换
使用命令行参数调用cvs2git麻烦、可重用性差,而且可配置项有限。采用cvs2git配置文件模式运行不但能够简化cvs2git的命令行参数,而且还能够提供更多的、命令行无法提供的配置项,可以更精确地对CVS到Git版本库的转换进行定制。
34.3.1 配置文件解说
cvs2svn软件包提供了一个cvs2git的配置示例文件,见源码中的文件cvs2git-example.options[1]。
将该示例文件在本地复制一份对其进行更改。该文件是Python代码格式,以“#”(井号)开始的行是注释,不要随意更改文件缩进,因为缩进也是Python语法的一部分。可以考虑针对下列的选项进行定制。
(1)设置CVS版本库位置。
使用配置文件方式运行cvs2git,只能在配置文件中设置要转换的CVS版本库位置,而不能在命令行进行设置。具体来说,是在配置文件最后面的run_options的set_project方法中指定。
run_options.set_project( #CVS版本库的位置(不是工作区,而是包含,v文件的版本库) #可以是版本库下的子目录。 r '/cvshome/user/jiangxin/homepage/worldhello/archive/2003/',
(2)设置导出文件的位置。
将CVS版本文件的内容导出至blob导出文件:cvs2svn-tmp/git-blob.dat。
还设置了使用更稳定的"cvs"命令进行导出。
ctx.revision_collector=GitRevisionCollector( 'cvs2svn-tmp/git-blob.dat', #RCSRevisionReader(co_executable=r 'co'), CVSRevisionReader(cvs_executable=r 'cvs'), )
另外一个导出文件的位置设定。默认位置:cvs2svn-tmp/git-dump.dat。
ctx.output_option=GitOutputOption( os.path.join(ctx.tmpdir,'git-dump.dat'), #The blobs will be written via the revision recorder,so in #OutputPass we only have to emit references to the blob marks: GitRevisionMarkWriter(), #Optional map from CVS author names to git author names: author_transforms=author_transforms, )
(2)设置无提交用户信息时使用的用户名。这个用户名可以用接下来的用户映射转换为Git用户名。
ctx.username='cvs2svn'
(3)建立CVS用户和Git用户之间的映射。Git用户名可以用Python的元组(tuple)语法(name,email)或字符串u 'name<email>'[2]来表示。
author_transforms={ 'jiangxin':('Jiang Xin','jiangxin@ossxp.com'), 'dev1' :u'开发者1<dev1@ossxp.com>', 'cvs2svn' : 'cvs2svn<admin@example.com>', }
(4)字符集编码。即如何转换日志中的用户名、提交说明及文件名的编码。
对于可能在日志中出现的中文,必须做出与下面类似的设置。编码的顺序对输出会有影响,一般将'utf8'放在'gbk'之前,以保证当日志中同时出现两种编码时都能正常转换。(这是因为部分中文的UTF8编码在GBK中也存在着古怪的对应。)
ctx.cvs_author_decoder=CVSTextDecoder( [ 'utf8', 'gbk', ], fallback_encoding='gbk' ) ctx.cvs_log_decoder=CVSTextDecoder( [ 'utf8', 'gbk', ], fallback_encoding='gbk' ) ctx.cvs_filename_decoder=CVSTextDecoder( [ 'utf8', 'gbk', ], #fallback_encoding='ascii' )
(5)是否忽略.cvsignore文件?默认保留.cvsignore文件。
无论选择保留或是不保留,最好在转换后手工进行.cvsignore到.gitignore的转换。因为cvs2git不能自动将.cvsignore文件转换为.gitignore文件。
ctx.keep_cvsignore=True
(6)对文件换行符等的处理。下面的配置原本是针对CVS到Subversion的属性转换,但是也会影响到Git转换时的换行符设置。维持默认值比较安全。
ctx.file_property_setters.extend([ #基于配置文件设置文件的mime类型 #MimeMapper(r '/etc/mime.types',ignore_case=False), #对于二进制文件(-kb模式)不设置svn:eol-style属性(对于Subversion来说) CVSBinaryFileEOLStyleSetter(), #如果文件是二进制,并且还没有设置svn:mime-type,将其设置为 'application/octet-stream'。 CVSBinaryFileDefaultMimeTypeSetter(), #如果希望根据文件的mime类型来判断文件的换行符,打开下面的注释 #EOLStyleFromMimeTypeSetter(), #如果上面的规则没有为文件设置换行符类型,则为svn:eol-style设置默认类型 #(二进制文件除外) #默认把文件视为二进制,不为其设置换行符类型,这样最安全 #如果确认CVS的二进制文件都已经设置了-kb参数,或者使用上面的规则能够对 文件类型做出正确判断,也可以使用下面的参数为非二进制文件设置默认换行符号 ## 'native':服务器端文件的换行符保存为LF,客户端根据需要自动转换 ## 'CRLF':服务器端文件的换行符保存为CRLF,客户端亦为CRLF ## 'CR':服务器端文件的换行符保存为CR,客户端亦为CR ## 'LF':服务器端文件的换行符保存为LF,客户端亦为LF DefaultEOLStyleSetter(None), #如果文件没有设置svn:eol-style,也不为其设置svn:keywords属性 SVNBinaryFileKeywordsPropertySetter(), #如果没有设置svn:keywords,基于文件的CVS模式进行设置。 KeywordsPropertySetter(config.SVN_KEYWORDS_VALUE), #设置文件的svn:executable属性,如果文件在CVS中标记为可执行文件。 ExecutablePropertySetter(), ])
(7)是否只迁移主线,忽略分支和里程碑?
默认对所有分支和里程碑都进行转换。如果选择忽略分支和里程碑,则将False修改为True。
ctx.trunk_only=False
(8)分支和里程碑的迁移及转换。
global_symbol_strategy_rules=[ #和正则表达式匹配的CVS标识,转换为Git的分支 #ForceBranchRegexpStrategyRule(r 'branch.*'), #和正则表达式匹配的CVS标识,转换为Git的里程碑 #ForceTagRegexpStrategyRule(r 'tag.*'), #忽略和正则表达式匹配的CVS标识,不进行(到Git分支/里程碑)转换 #ExcludeRegexpStrategyRule(r 'unknown-.*'), #有歧义的CVS标识的处理选项 #默认根据使用频率自动确定转换为分支或里程碑 HeuristicStrategyRule(), #或者全部转换为分支 #AllBranchRule(), #或者全部转换为里程碑 #AllTagRule(), … run_options.set_project( … #A list of symbol transformations that can be used to rename symbols in this project. symbol_transforms=[ #是否需要重新命名里程碑?第一个参数用于匹配,第二个参数用于替换。 #RegexpSymbolTransform(r 'release-(\d+)_(\d+)',r 'release-\1.\2'), #RegexpSymbolTransform(r 'release-(\d+)(\d+)(\d+)',r 'release-\1.\2.\3'),
[1]http://repo.or.cz/w/cvs2svn.git/blob/HEAD:/cvs2git-example.options
[2]字符串前面的字符u声明该字符串以Unicode格式保存。
