本章内容适用于下列用户:
-
从 CVS 迁移到 Subversion 的用户
-
在 Linux 下工作的用户
-
Subversion 管理员
目录
[隐藏]
|
1. Subversion 和 CVS 对照表
比较项目 |
CVS |
Subversion |
服务器端存储 |
|
如何备份版本库? |
工作目录结构 |
|
尝试复制、移动工作目录 |
版本号 |
|
|
协议 |
|
|
创建版本库 |
|
|
权限设置 |
|
|
脚本扩展 |
|
SVN 有几个钩子脚本? |
批量导入 |
|
|
显示模块/项目列表 |
需要手工设置 CVSROOT/modules |
服务器本身即支持 |
检出 |
|
|
添加文件和目录 |
|
|
查看每一行的更改信息 |
|
blame 比 annotate 更形象 |
文件比较 |
|
|
删除文件和目录 |
|
|
反删除 |
|
直接 svn add 会怎么样? Defect or feature? |
重命名 |
|
|
提交 |
|
|
查看Log |
|
|
查看分支和TAG |
|
|
查看文件修改状态 |
|
|
更新 |
|
不显示当前文件状态 |
文件状态指示符 |
|
|
检出历史版本 / 输出到stdout |
检出历史版本,以免 sticky 状态 |
|
文件复制 |
|
还是文件反删除的手段之一
参见:用合并命令还原文件 |
创建分支 |
|
相当于目录复制。查看一下服务器端的变化,理解SVN的轻量级分支创建 |
创建里程碑 |
|
相当于目录复制。查看一下服务器端的变化 |
口令缓存 |
|
发布机上提交代码,为什么提交者不是我? |
关键字扩展 |
|
|
换行符 |
|
更改换行符后,有时整个文件要重新提交,为什么? |
分支合并 |
需要手动记录合并动作,以免日后重复合并造成无谓冲突 |
还是文件恢复/反删除的手段之一
参见:用拷贝命令反删除文件 |
冲突解决 |
|
|
回滚 |
|
|
属性 |
|
|
代码库整理 |
|
|
忽略文件 |
|
|
整合外部版本库 |
|
|
切换开发分支 |
|
|
服务器更换域名/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/
群英汇帮助类