本章内容适用于下列用户:
Contents
|
1. Subversion 和 CVS 对照表
比较项目 |
CVS |
Subversion |
服务器端存储 |
|
|
工作目录结构 |
|
|
版本号 |
|
|
协议 |
|
|
创建版本库 |
|
|
权限设置 |
|
|
脚本扩展 |
|
|
批量导入 |
|
|
显示模块/项目列表 |
|
|
检出 |
|
|
添加文件和目录 |
|
|
查看每一行的更改信息 |
|
|
文件比较 |
|
|
删除文件和目录 |
|
|
反删除 |
|
|
重命名 |
|
|
提交 |
|
|
查看Log |
|
|
查看分支和TAG |
|
|
查看文件修改状态 |
|
|
更新 |
|
|
文件状态指示符 |
|
|
检出历史版本 / 输出到stdout |
|
|
文件复制 |
|
|
创建分支 |
|
|
创建里程碑 |
|
|
口令缓存 |
|
|
关键字扩展 |
|
|
换行符 |
|
|
分支合并 |
|
|
冲突解决 |
|
|
回滚 |
|
|
属性 |
|
|
代码库整理 |
|
|
忽略文件 |
|
|
整合外部版本库 |
|
|
切换开发分支 |
|
|
服务器更换域名/IP/版本库名称 |
|
|
2. 版本库整理相关命令
2.1. 导出 ── svnadmin dump
- svnadmin dump
该命令将版本库导出到一个格式文件,该导出文件包含所有版本库历史信息,可以用于版本库备份,或导入其它版本库。
用法:
svnadmin dump REPOS_PATH [-r LOWER[:UPPER]] [--incremental] [-q]
参数:
- REPOS_PATH
必须是本地路径。如: /opt/svn/svnroot/repos2/
- -r LOWER[:UPPER]
导出从版本 LOWER 到版本 UPPER(或仅导出 LOWER 版本,如果UPPER不提供)的版本库历史。如果不提供该参数,则导出全部历史。
- --incremental
导出的第一个版本是和前一次版本的变更,用于增量备份和导入。如果不提供该参数,第一个导出版本是完整内容。
- -q
在标准错误输出不显示进度 (仅错误)
- --help
查看 svnadmin dump 命令的用法
示例:
svnadmin dump /opt/svn/svnroot/repos2 > dumpfile.txt -- 将版本库 repos2 导出到文件 dumpfile.txt
2.2. 导入 ── svnadmin load
- svnadmin load
从标准输入读取版本库转存(导出)的格式文件,并导入到新版本库中。
用法:
svnadmin load [--ignore-uuid|--force-uuid] [--use-pre-commit-hook] [--use-post-commit-hook] [--parent-dir ARG] REPOS_PATH
参数:
- REPOS_PATH
必须是本地路径。如: /opt/svn/svnroot/repos2/。如果是空版本库(即刚刚用 svnadmin create 创建),则会用标准输入流中的 UUID 替换该库的 UUID。
- --ignore-uuid
即使目标版本库是空的,也不用标准输入流中的 UUID 替换版本库的 UUID。
- --force-uuid
即使目标版本库非空(含一次以上的提交),如果流中存在UUID,则设定为版本库的 UUID。
- --use-pre-commit-hook
提交版本前调用 pre-commit 钩子
- --use-post-commit-hook
提交版本后调用 post-commit 钩子
- --parent-dir ARG
加载到版本库指定的目录中,缺省加载到根
- -q [--quiet]
在标准错误输出不显示进度 (仅错误)
- --help
查看 svnadmin load 命令的用法
示例:
svnadmin load --parent-dir new/subdir/for/project /opt/svn/svnroot/new_repos < dumpfile.txt
2.3. 裁减 ── svndumpfilter
- svndumpfilter
从标准输入读取版本库转存(导出)的格式文件,并导入到新版本库中。
用法:
svndumpfilter help [include] [exclude] svndumpfilter exclude PATH_PREFIX ... [OPTIONS ...] svndumpfilter include PATH_PREFIX ... [OPTIONS ...]
子命令:
- exclude
从标准输入中排除某个/某些路径下的内容,仅输出其它未指定路径下的内容。
- include
仅从标准输入中包含某个/某些路径下的内容,其它未指定的路径下的内容被抛弃。
- help
查看帮助。后面提供 include 或者 exclude 参数,则输出 include 或 exclude 子命令的详细帮助。
参数:
- PATH_PREFIX ...
路径前缀。可以是空格分隔的多个前缀,将对 svn 导出文件中属于该前缀之下路径的文件或者目录进行相应的处理(忽略或者包含)。前缀如果不包含"/",将会自动添加一个"/"。
- --drop-empty-revs
删除因过滤而产生的空版本。
- --renumber-revs
过滤后重编余下的版本。
- --skip-missing-merge-sources
跳过缺少的合并源。
- --targets ARG
传递文件 ARG 的内容为额外的参数
- --preserve-revprops
不过滤版本属性。
- --quiet
不显示过滤的统计数据。
示例:
将 svn 的 dump 文件 inputfile 中出现的以 /trunk/module1 或者 /trunk/module2 为前缀的文件和路径忽略,其余文件和目录转存到文件 filteredfile。
$ svndumpfilter --drop-empty-revs --renumber-revs --skip-missing-merge-sources exclude /trunk/module1 /trunk/module2 < inputfile > filteredfile
2.4. 导入后目录降级
- 导入后目录降级
即导入到一个子目录中。如旧版本库 old_repos 中的 /trunk, /tags, /branches 等目录,导入到新库 new_repos 中的新路径为 repos1/trunk, repos1/tags, repos1/branches。
实现目录降级非常简单:
在新版本库中创建要导入到的子目录。如在新版本库 new_repos 中创建目录 repos1:
svn mkdir file:///opt/svn/svnroot/new_repos/repos1 -m "create new subdir for import"
在使用 svnadmin load 导入时,提供参数 --parent-dir DIR_NAME。如导入到新库的 repos1 目录:
svnadmin load --parent-dir repos1 /opt/svn/svnroot/new_repos < old_repos_dumpfile
2.5. 导入后目录升级
- 导入后目录升级
即从旧版本的一个子目录的导出内容,导入到一个新版本库的根目录中。如旧版本库 old_repos 中的 repos1/trunk, repos1/tags, repos1/branches 等目录,导入到新库 new_repos 中的新路径为 trunk, tags, branches。
实现目录升级稍微复杂,需要对导出文件进行替换操作。
将旧版本的 repos1 模块下的文件(repos1/trunk, repos1/tags, repos1/branches)导出:
$ svnadmin dump /opt/svn/svnroot/old_repos | svndumpfilter include /repos1 --drop-empty-revs --renumber-revs > filteredfile 版本被重新编号如下: 10 => 7 9 => 6 8 => 5 7 => 4 6 => 3 5 => 2 4 => (丢弃) 3 => 1 2 => (丢弃) 1 => (丢弃) 0 => 0
将导出文件 filteredfile 中的路径 repos1 替换为空。
sed -e "s@^\(Node-path: \|Node-copyfrom-path: \)repos1/@\1@" filteredfile > filteredfile.fixed
用替换过的导出文件,导入到新库。如导入到 new_repos 版本库:
svnadmin load /opt/svn/svnroot/new_repos < filteredfile.fixed
删除新库中可能包含的 /repos1
如果要避免在新库中出现 /repos1 空目录,在导出旧版本库时使用 --revision X:Y 参数。X 是创建 /repos1 目录后的下一个版本,Y是版本库最新版本。
3. 版本库转换相关命令
3.1. cvs2svn
- cvs2svn
将 CVS 的版本库转换为 Subversion 的版本库,并保持全部历史数据,包括里程碑和分支。
cvs2svn 可以将 CVS 库直接转换并导入到一个新的 Subversion 版本库中
cvs2svn 还可以将 CVS 版本库导出到一个文件中,该文件和 svnadmin dump 导出文件格式相同。
推荐使用该方法。
用法:
cvs2svn [OPTION...] OUTPUT-OPTION CVS-REPOS-PATH
即 cvs2svn 除可选参数外,需要指定 输出选项 和 CVS版本库路径
CVS版本库路径:
- CVS-REPOS-PATH
CVS 版本库的绝对路径。如: /cvshome/project1
输出选项: 输出选项包含一系列参数设置,用于设定CVS版本库转换后转存在一个导出文件,还是直接导入版本库中。
导入到版本库(不推荐):
- -s, --svnrepos=PATH
直接导入到 SVN 版本库中。SVN 版本库由 <PATH> 指定
- --existing-svnrepos
导入到由 --svnrepos 设定的已经存在的版本库中,否则创建一个新的版本库。版本库名称已经由 --svnrepos 进行设定。
导入到文件(推荐):
- --dumpfile=PATH
导出到文件
可选参数
换行符转换策略
缺省不进行转换。即所有文件不设置 svn:eol-style。优点是:安全,不会造成误判。缺点是:转换为 SVN 版本库后,在 Windows 上检出,文件换行符都是LF的 Unix 格式换行符。
使用 --default-eol=native 参数
使用 --default-eol=native,将自动为 CVS 中非二进制文件设置属性 svn:eol-style 为 native。
缺点: 如果 CVS 某些二进制文件(如 .gif 文件)没有设置 -kb 模式,将会造成灾难,数据损坏。
使用 --auto-props, --mime-types, 和 --eol-from-mime-type 参数精细调整换行符
- --eol-from-mime-type
根据文件的 mime type 设置 svn:eol-style。与 --mime-types=FILE 或者 --auto-props 配合使用有效。
- --auto-props=FILE
参考自动属性设置为文件设置属性和换行符标记,指定的文件为 svn 配置文件,包含 auto-props 小节。
- --mime-types=FILE
指定一个 apache 风格的 mime.types 文件用于参照设定 svn:mime-type。如果还使用了 --eol-from-mime-type 参数,则参照扩展名确定文件的 mime-type,进而设置换行符格式
字符集设置
用 --encoding=ENC 设置字符集。
首先确认一下 CVS 中字符集设置: 文件名、提交说明、用户名。(文件内容除外)
log 的字符集。可以打开 *,v 文件,查看log 是否有乱码。一般字符集是 gbk。
文件名的字符集。查看 CVS 库中的文件。如果中文文件名能够显示,则是和当前编码一致,可能已经是 UTF-8
log 和 文件名的字符集编码不同的原因可能是:文件复制之后,文件名自动转换为该平台的编码。而 log 是保存在文件 *,v 中,不会改变
可以用多个 --encoding=ENC 参数。例如:
cvs2svn --dumpfile=dump.txt --encoding=utf-8 --encoding=gbk /cvshome/project1/
--fallback-encoding=ENC 设置最后的防线
关键字扩展?
缺省将所有非 -kb 文件设置 svn:keywords 属性,值为: "author id date"
如果设置 --keywords-off,则不再为任何文件设置 svn:keywords
检出 CVS 模式
缺省使用 --use-internal-co, 即用 cvs2svn 自己的方法检出,速度快,但是消耗磁盘空间。
如果磁盘空间紧张,使用 --use-cvs 参数
尽量不要使用 --use-rcs,因为可能不能正确转换中文的提交说明
是否导出里程碑和分支?
仅导出主线: --trunk-only
用 --exclude=REGEXP 参数排除某些里程碑/分支
岐义里程碑/分支名处理。出现岐义,是因为 CVS 的里程碑/分支 创建的随意性,有可能在不同的文件存在同名的标签,一些文件的标签是里程碑,而另外一些同名的是里程碑。
参数 --symbol-default=OPT, --force-branch=REGEXP, --force-tag=REGEXP, --symbol-hints=PATH, --write-symbol-info=PATH 可以选择用于处理岐义。
里程碑重命名
--symbol-transform 参数可以实现 CVS 里程碑名称转换为新的 SVN 里程碑名称
示例
cvs2svn --symbol-transform='([0-9])-(.*):release-\1.\2' -s /svnhome/project1 /cvshome/project1 会实现: 1-0 → release-1.0 1-1 → release-1.1 2-0 → release-2.0
示例:
cvs2svn --dumpfile=dump.txt \ --use-cvs --encoding=utf-8 --encoding=gbk --tmpdir=tmp \ --mime-types=/etc/mime.types --eol-from-mime-type \ --symbol-transform='(?<=[0-9])-(?=[0-9]):.' \ /cvshome/project1/