在公司也有一段时间了,使用svn操作进行style发布,一直以来都是生硬的使用几个单一的命令来完成,也没用真正理解命令的含义。准备在这篇文档里留下有关这方面的知识。要不断的学习,记录学习总结 。
学习文档一:http://svnbook.red-bean.com/
官方文档翻译版: http://www.subversion.org.cn/svnbook/1.4/
svn 自带帮助: svn help 命令
网友文章:http://huaaqingchen.blog.sohu.com/107567483.html
1, 打印工作拷贝文件和目录的状态:svn st [--show-updates][--verbose] ; 简写:svn st [-u][-v]
? 不在版本库中
M 文件被修改
C 文件冲突
A 预定加入版本库
K 被锁定
G 表示代码合并成功
不加选项:通过本地的.svn文件记录查看工作拷贝文件和目录的状态
-u: 需要与版本库中的最新状态比较,并指出更新 。 如有更新打印出来在第二列用*号表示
-v: 为修改的文件和目录可要打印
(1).
$ svn st --show-updates --verbose
212055 205254 daniel.xud nav-v1.js
M * 212055 212055 rocket.xuj js-gb2312.js
212055 211858 daniel.xud top-merge.js
212055 205254 daniel.xud head.js
212055 212055 rocket.xuj .
Status against revision: 212061
星号:如果你现在执行svn update ,你的js-gb2312.js会被更新,这告诉你许多有用的信息—你可以在提交之前,需要使用更新操作得到文件js-gb2312.js的更新,或者说文件已经过时,版本库会拒绝了你的提交。
2. svn copy — 拷贝工作拷贝的一个文件或目录到版本库
svn copy SRC DST
如果: WC -> WC: 拷贝并且预定一个添加的项目(包含历史) URL -> URL: 完全的服务器端拷贝,通常用在分支和标签。
2, svn co
在本机创建一个项目的“本地拷贝 ”,这个拷贝包括了命令行指定版本库中的HEAD
(最新的)版本:
$ svn checkout http://svn.collab.net/repos/svn/trunk
A trunk/Makefile.in
A trunk/ac-helpers
A trunk/ac-helpers/install.sh
A trunk/ac-helpers/install-sh
A trunk/build.conf
…
Checked out revision 8810.
你也完全可以通过输入特定URL取出任意深度的子目录:
$ svn checkout /
http://svn.collab.net/repos/svn/trunk/subversion/tests/cmdline/
A cmdline/revert_tests.py
A cmdline/diff_tests.py
A cmdline/autoprop_tests.py
A cmdline/xmltests
A cmdline/xmltests/svn-test.sh
…
Checked out revision 8810.
把你的工作拷贝放到subv
而不是和前面那样放到trunk
,如果subv
不存在,将会自动创建:
$ svn checkout http://svn.collab.net/repos/svn/trunk subv
A subv/Makefile.in
A subv/ac-helpers
A subv/ac-helpers/install.sh
A subv/ac-helpers/install-sh
A subv/build.conf
…
Checked out revision 8810.
3, svn up:
当你在一个团队的项目里工作时,你希望更新你的工作拷贝得到所有其他人这段时间作出的修改,使用svn update 让你的工作拷贝与最新的版本同步:
$ svn update
U foo.c
U bar.c
Updated to revision 2.
当服务器通过svn update 将修改传递到你的工作拷贝时,每一个项目之前会有一个字母,来让你知道Subversion为保持最新对你的工作拷贝作了哪些工作。关于这些字母的详细含义:
A 添加:
D 删除
U 更新
C 冲突
G 合并
R 被同名文件替代
2) 本地回滚 (workingcopy是正常的) :它会把工作拷贝更新到你用--revision
指定的修订版本。为了保持同步,也会删除所有在工作拷贝发现的无效锁定。
$ svn update -r30
A newdir/README
D newdir/toggle.c
D newdir/disclose.c
D newdir/launch.c
U foo.c
Updated to revision 30.
4,svn log:(查看生成版本的操作信息记录)
对于分支操作:
1)查看分支拷贝副本的log。(其实是分支的log信息,从任何分支拷贝副本里看也是看分支上的所有log)
~ svn log [本地path/分支url] :打印出该分支的所有生成版本的信息(包括该分支以前的主干的log日志,因为该分支是从主干copy过来的。)
~ svn log [本地path/分支url] --stop-on-copy : 打印出该分支的创建后生成版本的操作信息。
~ svn log [本地path/分支url] -rHEAD:211720 : 打印出该分支的在指定版本中的能生成版本的操作信息。
5,svn diff — 比较两条路径的区别。
$ svn diff COMMITTERS :比较BASE
和你的工作拷贝
$ svn diff -c 9115 COMMITTERS: 查看文件COMMITTERS
在修订版本9115修改的内容
$ svn diff -r 3900 COMMITTERS:查看你的工作拷贝对旧的修订版本的修改
$ svn diff -r 3000:3500 http://svn.collab.net/repos/svn/trunk/COMMITTERS: 使用范围符号来比较修订版本3000和3500(在这种情况下只能传递一个URL),即可以用来查看主干的新版本文件的变化
$ svn diff -r 3000:3500 http://svn.collab.net/repos/svn/trunk: 使用范围符号比较修订版本3000和3500trunk
中的所有文件
$ svn diff -r 3000:3500 COMMITTERS : 如果你有工作拷贝,你不必输入这么长的URL
5, svn list — 列出版本库目录的条目。
svn list [TARGET[@REV]...]
列出每一个
TARGET
文件和TARGET
目录的内容,如果TARGET
是工作拷贝路径,会使用对应的版本库URL。
缺省的
TARGET
是“.
”,意味着当前工作拷贝的版本库URL。
例子:
$ svn list --verbose repos 或者 $ svn list --v repos
16 sally 28361 Jan 16 23:18 README.txt
27 sally 0 Jan 18 15:27 INSTALL
24 harry Jan 18 11:27 examples/
可以使用unix下命令来进行对比,查看有哪些文件还没有加入版本库:
$ list -l
16 sally 28361 Jan 16 23:18 README.txt
27 sally 0 Jan 18 15:27 INSTALL
24 harry Jan 18 11:27 examples/
24 harry1 Jan 19 11:27 exa/
6,svn merge — 应用两组源文件的差别到工作拷贝路径。
如果你对合并是如何工作的感到迷惑,这并不奇怪,很多人和你一样。许多新用户(特别是对版本控制很陌生的用户)会对这个命令的正确语法感到不知所措,不知道怎样和什么时候使用这个特性,不要害怕,这个命令实际上比你想象的简单!有一个简单的技巧来帮助你理解svn merge
的行为。
迷惑的主要原因是这个命令的名称
,术语“合并
”不知什么原因被用来表明分支的组合,或者是其他什么神奇的数据混合,这不是事实,一个更好的名称应该是svn diff-and-apply
,这是发生的所有事件:首先两个版本库树比较,然后将区别应用到本地拷贝。
这个命令包括三个参数:
初始的版本树(通常叫做比较的左边
),
最终的版本树(通常叫做比较的右边
),
一个接收区别的工作拷贝(通常叫做合并的目标
)。
一旦这三个参数指定以后,两个目录树将要做比较,比较结果将会作为本地修改应用到目标工作拷贝,当命令结束后,结果同你手工修改或者是使用svn add
或svn delete
没有什么区别,如果你喜欢这结果,你可以提交,如果不喜欢,你可以使用svn revert
恢复修改。
svn merge
的语法允许非常灵活的指定三个必要的参数,如下是一些例子:
$ svn merge http://svn.example.com/repos/branch1@150 /
http://svn.example.com/repos/branch2@212 /
my-working-copy
$ svn merge -r 100:200 http://svn.example.com/repos/trunk my-working-copy
$ svn merge -r 100:200 http://svn.example.com/repos/trunk
第一种语法使用URL@REV
的形式直接列出了所有参数,第二种语法可以用来作为比较同一个URL的不同版本的简略写法,最后一种语法表示工作拷贝是可选的,如果省略,默认是当前目录。
例子
1. 将一个分支合并回主干(假定你有一份主干的工作拷贝,分支在修订版本250创建):
$ svn merge -r 250:HEAD http://svn.red-bean.com/repos/branches/my-branch
U myproj/tiny.txt
U myproj/thhgttg.txt
U myproj/win.txt
U myproj/flo.txt
2.合并一个单独文件的修改:
$ cd myproj
$ svn merge -r 30:31 thhgttg.txt
U thhgttg.txt
所以回滚本地已经提交的代码到旧版本,可以如下操作
典型的操作过程如下:
1)、保证我们拿到的是最新代码:
svn update
假设是28版本。
2)、然后找出要移除的确切版本:
svn log contacts.java
根据log怀疑是27版本改坏的,比较一下:
svn diff -r 26:27 contacts.java
发现果真是27版本坏事。
3)、撤销27版本的改动:
svn merge -r 27:26 contacts.java
为了保险起见,再次确认合并的结果:
svn diff contacts.java
发现已正确撤销了改动,提交。
4)、提交改动
svn commit -m "Revert wrong change from r27"
提交后版本变成了29。
自己测试了下,好像只能针对一个文件 进行操作。
4,修订版本(repository)关键字
Subversion客户端可以理解一些修订版本关键字 ,这些关键字可以用来代替--revision (r)
的数字参数,这会被Subversion解释到特定修订版本号:
HEAD: 版本库中最新的(或者是“最年轻的 ”)版本。
BASE: 工作拷贝中一个条目的修订版本号,如果这个版本在本地修改了,则“BASE版本 ”就是这个条目在本地未修改的版本。
COMMITTED: 项目最近修改的修订版本,与BASE
相同或更早。
PREV: 一个项目最后修改版本之前 的那个版本,技术上可以认为是COMMITTED
-1。
因为可以从描述中得到,关键字PREV
,BASE
和COMMITTED
只在引用工作拷贝路径时使用,而不能用于版本库URL,而关键字HEAD
则可以用于两种路径类型。
5. svn revert — 取消所有的本地编辑 。(即放弃为提交的本地修改)
选项
--targets FILENAME
--recursive (-R): 递归处理目录中的所有文件
例子
$ svn revert foo.c Reverted foo.c
如果你希望恢复一整个目录的文件,可以使用--recursive
选项:
$ svn revert --recursive .
Reverted newdir/afile
$ svn revert mistake.txt whoops
如果你没有给svn revert 提供了目标,它不会做任何事情—为了保护你不小心失去对工作拷贝的修改,svn revert 需要你提供至少一个目标。