SVN 版本控制工具
SVN
Apache Subversion(SVN)是一个中心化的版本控制软件,功能稳定,具有优异的跨平台支持。SVN 理解和使用比Git简单很多。同为版本控制系统,尽管 Git 凭借其丰富且优秀的特性(更好的性能、更高的可靠性、分布式模型和分支处理等)成为了目前主流的 VCS,但 SVN 在不少领域也仍然很受欢迎,非常适合用于大型项目。
SVN 由 CollabNet 公司于2000年创建,2009年11月提交至 Apache Incubator 进行孵化,并于2010年2月成为 Apache 基金会的顶级项目。
命令缩写
全称 | 简写 |
---|---|
checkout | co |
commit | ci |
status | st |
list | ls |
copy | cp |
可以通过手册查看svn命令的用法:
svn [command] --help 或者 svn help [command]
查看版本库文件目录
svn list/ls svn://路径(目录或文件的全路径)
检出 checkout
svn co http://路径(目录或文件的全路径) [本地目录全路径] [--username 用户名 --password 密码]
地址除了http/htttps的网址形式,还可以是svn地址格式:username和password均是可选项,在输密码的时候直接回车或者密码错误均会重新输入用户名。
不指定本地目录全路径,则检出到当前目录下。
添加新文件 add
svn add 文件名(可使用通配符)
svn commit -m "msg" *.txt # 可直接在commit时add文件
与git有所区别,git是每次修改文件后都需要add,然后再commit到本地仓库。而svn则add一次后再次修改不需要重复add,可直接commit到远程中心仓库。
提交 commit
svn commit/ci -m 'msg' [文件名]
与git不同的是svn会直接提交到中心仓库,需联网。如果后边不跟文件名,则提交已经处于版本中(add过)的修改文件(git status显示状态为M的文件)。提交的时候如果提示过期冲突,需要先 update 修改文件,然后清除svn resolved,最后再提交。
更新文件 update
svn update [文件名或目录]
后面没有目录,默认将当前目录以及子目录下的所有文件都更新到最新版本
svn update -r 修正版本 文件名
将版本库中的文件还原到修正版本(revision)
删除文件 delete
svn delete svn://路径(目录或文件的全路径) -m “删除备注信息文本”
等同于如下操作:
svn delete 文件名
svn ci -m “删除备注信息文本”
查看日志 log
svn log 文件名
需联网,-l 5 限制只显示前5条,否则会全部显示。
导出 export
导出一个干净的不带.svn文件夹的目录树:
svn export [-r 版本号] http://路径(目录或文件的全路径) [本地目录全路径]
如果指定了修订版本号,会导出相应的版本,如果没有指定修订版本,则会导出最新的,导出到指定位置。如果省略本地目录全路径,URL的最后一部分会作为本地目录的名字。
查看详情 info
svn info [文件名]
可以查看svn的中心仓库的地址、版本号、修改日期等信息。
查看文件状态 status
svn status/st 目录路径/名
查看目录下的文件和子目录的状态,正常状态不显示【?:不在svn的控制中; M:内容被修改;C:发生冲突;A:预定加入到版本库;K:被锁定】
比较差异 diff
svn diff 文件名
svn diff -r 修正版本号m:修正版本号n 文件名
比较当前版本与历史版本:svn diff -r34 file
恢复本地修改 revert
丢弃本地未提交的修改:
svn revert [-R/--recursive] 文件/文件夹
丢弃本地对文件的修改,--recursive表示对层次的整个目录丢弃修改。
svn status、svn diff和 svn revert这三条命令在没有网络的情况下也可以执行,因为在本地的.svn中保留了本地版本的原始拷贝。
改动已提交的修改
假设最新版版本号是new,想回滚到版本old,采用merge进行合并:
svn merge -r new:old 文件名
可以在merge的前后使用svn diff [-r new:old]来查看
再次提交回滚的代码:
svn commit -m "Revert revision from r28 to r25, cause of ..."
拷贝分支 copy
svn copy branchA branchB -m "tag B"
可以用来打tag,或者里程碑。
合并分支 merge
svn merge branchA branchB
把对branchA的修改合并到分支branchB
转换分支
转换工作拷贝
svn switch [--revision/-r version] 地址
命令改变存在的工作拷贝到另一个分支.
常用名称:
- trunk(主干|主线|主分支):是用来做主方向开发的,新功能的开发应放在主线中,当模块开发完成后,需要修改,就用branch。
- branch(分支):分支开发和主线开发是可以同时进行的,也就是并行开发,分支通常用于修复bug时使用
- tag(标记):用于标记某个可用的版本,可以标记已经上线发布的版本,也可以标记正在测试的版本,通常是只读的
获取历史版本文件
回退到某版本(将历史版本文件放到当前工作区):
svn update -r 666 file
仅查看:
svn cat -r 666 file | less
svn cat -r 666 file | vim - # 设置语法高亮::set syntax=java
解决树冲突(tree conflict)
树冲突的现象都是一端modified, 另一端missing. 树冲突不仅要解决目录结构冲突, 同时可能需要解决普通的文件内容冲突.
用svn status(st)查看哪些文件冲突了,用svn info查看冲突信息.
冲突处理
我们按文件missing原因和需不需要分类处理
1. 文件被删除, 不再需要
这种情况就很好处理, 使用相关SVN命令将其删了就可以了.
- 服务端modified, 本地missing, 该文件不要了. 这种情况本地不会存在该文件, 直接调用resolve就可以了.
#标记冲突已解决(使用本地的状态, 本地该文件的状态是Delete, 提交后服务端对应的文件就会被删除)
$ svn resolve --accept=working file_old.c
- 本地modified, 服务端missing, 该文件不要了. 这种情况本地存在改文件, 所以强制删掉本地的, 再调用resolve
#强制删除本地的文件(发生的文件不加--force是删不掉的)
$ svn delete --force file_old.c
#标记冲突已解决(使用服务器状态)
$ svn resolve --accept=theirs-conflict file_old.c
#或者使用本地状态也可以, 应该本地的状态跟服务一致了(都是Delete)
$ svn resolve --accept=working file_old.c
2. 文件被删除, 仍然需要
这种情况可能是由于文件被不小心删除了, 重新加回svn就可以了.
- 服务端modified, 本地missing, 选择their conflict就可以了
svn resolve --accept=theirs-conflict file.c
- 本地modified, 服务端missing
svn resolve --accept=working file.c
svn设置
设置忽略文件列表
SVN设置忽略文件列表:修改版本库的相关属性
svn propedit svn:ignore dir
其中 dir
就是你所想设置过滤文件列表的目录,执行命令之后,会出现编辑界面,按照空格将你想过滤文件(通常使用通配符的方式)以空格分开,保存退出即可。这个属性是针对版本库进行的修改,因此需要提交这个修改。svn:ignore是svn的一个参数。
注意:这个设置无法递归,也就是如果 dir 目录下还有子目录的话,是单独设置的。
设置提交文件类型
svn commit 时提示某文件编码有问题,如 xxx is not a GBK file. plz check svn:mime-type properties.
由于SVN要求的是GBK,而文件不满足要求,可以设置mime-type:
svn propset svn:mime-type 'type/plain' xxx
或者批量处理:find ./ -name '*.cpp' -exec svn propset svn:mime-type 'type/plain' {} ;
但是设置成'type/plain',在svn diff时会认为文件是二进制文件,无法比较,可以使用svn diff --force进行强制比较。更好的方式是设置成'text/plain'的文本类型。
设置diff工具:diff/vimdiff
~/.subversion/config中指定了diff工具wrapper: 例如/usr/local/bin/diffwrap.sh,其中的内容是:
DIFF="vimdiff"
LEFT=${6}
RIGHT=${7}
$DIFF $LEFT $RIGHT
可以通过在config中修改,或者在命令行svn diff --diff-cmd diff/vimdiff 来临时选择diff工具。