传送门
文章目录
subversion
虽然
git
在版本控制
领域称霸已久,但一些公司和团队出于某些原因还是对subversion
恋恋不舍。
通常情况下git用户
喜欢用命令行
,而subversion
用户则大部分会选择图形界面
(TortoiseSVN、VisualSVN、CollabNet、SlikSVN、WANdisco)。本文主要介绍如何用命令行来玩转subversion
。
import
将本地目录添加到SVN服务器上
svn import -m "for test" /home/frank/test/svn/svntest/ http:/127.0.0.1:9988/svn/xxx1/svntest
Committed revision 654.
说明:
-m
必填项,备注你的操作- 本地目录为绝对路径
- 远程目录不存在则自动创建
- 命令执行完你本地目录并没有
.svn
目录和版本信息,需要checkout
。
checkout
这个不知道怎么翻译合适,
检出
,克隆
,下载
,还是自己意会吧。
usage: checkout URL[@REV]… [PATH]
简写:co
$ svn co http:/127.0.0.1:9988/svn/xxx1/svntest
Checked out revision 655.
说明:
- 在当前目录
checkout
,当前目录下会自动创建版本库目录 - 可以在最后指定版本存放位置[PATH]
- 指定用户名和密码:–username 用户名 --password 密码
info
查看版本库信息
usage: info [TARGET[@REV]…]
$ svn info svntest/
$ svn info http:/127.0.0.1:9988/svn/xxx1/svntest
$ svn info
说明:
- 在有版本信息的本地目录直接执行svn info
- 指定本地目录
- 指定远程URL
上面三种效果一样
add
添加新文件或目录
$ touch test.txt
$ ls
test.txt
$ svn add test.txt
A test.txt
$ mkdir test
$ touch a.ini
$ touch b.ini
$ touch test/dir.txt
$ tree
.
├── a.ini
├── b.ini
├── test
│ └── dir.txt
└── test.txt
$ svn add *.ini
A a.ini
A b.ini
$ svn add test/
A test
A test/dir.txt
说明:
- 单文件添加
- 多文件添加
- 目录添加
commit
提交到版本库
usage: commit [PATH…]
$ svn commit -m "one file" test.txt
Adding test.txt
Transmitting file data .
Committed revision 661.
$ svn commit -m "dir" test/
Adding test
Adding test/dir.txt
Transmitting file data .
Committed revision 662.
$ svn commit -m "all"
Adding a.ini
Adding b.ini
Transmitting file data ..
Committed revision 663.
说明:
- 单文件提交
- 多文件提交
- 目录提交
status
查看文件或目录状态
status [PATH…]
$ svn st
M test.txt
A test1.txt
? test2.txt
$ svn st -q
M test.txt
A test1.txt
$
$ svn st -u
M 661 test.txt
A - test1.txt
? test2.txt
Status against revision: 664
$ svn st -v
655 654 xxx1 .
663 663 xxx1 a.ini
663 663 xxx1 b.ini
662 662 xxx1 test
662 662 xxx1 test/dir.txt
M 661 661 xxx1 test.txt
A - ? ? test1.txt
? test2.txt
说明:
-q
不显示未添加的文件-u
显示版本信息-v
显示全部信息:第二列显示工作版本号,第三和第四列显示最后一次修改的版本号和修改人
delete
删除文件
usage: 1. delete PATH…
2. delete URL…
简写:del, remove, rm
$ svn rm test1.txt
D test1.txt
$ svn st
D test1.txt
? test2.txt
$ svn del -m "" http:/127.0.0.1:9988/svn/xxx1/svntest/test.txt
Committed revision 667.
说明:
- 指定本地文件/目录删除
- 指定远程URL的文件
update
更新版本
usage: update [PATH…]
简写:up
$ svn up
Updating '.':
D test.txt
Updated to revision 667.
$ svn up -r 662 test.txt
Updating 'test.txt':
A test.txt
Updated to revision 662.
$ svn up
Updating '.':
D test.txt
Updated to revision 667.
- 可以指定路径或文件
- 第一列说明
A Added
D Deleted
U Updated
C Conflict
G Merged
E Existed
R Replaced - 更新到指定的版本
log
查看版本变化日志
usage: 1. log [PATH][@REV]
2. log URL[@REV] [PATH…]
$ svn log
$ svn log test.txt
$ svn log test.txt@662
$ svn log http:/127.0.0.1:9988/svn/xxx1/test.txt
$ svn log http:/127.0.0.1:9988/svn/xxx1 test.txt test1.txt
$ svn log http:/127.0.0.1:9988/svn/xxx1@662 test.txt test1.txt
带参数
$ svn log --diff -v -l 5
说明:
--diff
输出每次修改的内容-v
尽量详细的输出内容-l n
输出最新n次提交记录
diff
比较差异
usage: 1. diff [-c M | -r N[:M]] [TARGET[@REV]…]
2. diff [-r N[:M]] --old=OLD-TGT[@OLDREV] [–new=NEW-TGT[@NEWREV]]
[PATH…]
3. diff OLD-URL[@OLDREV] NEW-URL[@NEWREV]
简写:di
对比本地修改与服务器最新版本:
$ svn diff
$ svn diff test.txt
Index: test.txt
===================================================================
--- test.txt (revision 669)
+++ test.txt (working copy)
@@ -0,0 +1 @@
+aaaaaa
对比两个版本:
$ svn st -v
667 667 xxx1 .
670 670 xxx1 a.ini
667 663 xxx1 b.ini
667 662 xxx1 test
667 662 xxx1 test/dir.txt
M 669 669 xxx1 test.txt
? test2.txt
$ svn log a.ini
------------------------------------------------------------------------
r670 | xxx1 | 2020-02-12 19:04:48 +0800 (Wed, 12 Feb 2020) | 1 line
------------------------------------------------------------------------
r663 | xxx1 | 2020-02-12 18:13:59 +0800 (Wed, 12 Feb 2020) | 1 line
all
------------------------------------------------------------------------
$ svn diff -r 663:670 a.ini
Index: a.ini
===================================================================
--- a.ini (revision 663)
+++ a.ini (revision 670)
@@ -0,0 +1 @@
+nini
list
看看版本库或目录下文件/目录列表,常用在对远程版本库目录结构不了解时使用。
usage: list [TARGET[@REV]…]
简写:ls
$ svn ls http:/127.0.0.1:9988/svn/xxx1/svntest
a.ini
b.ini
test/
test.txt
$ svn list
a.ini
b.ini
test/
test1.txt
mkdir
在服务端或本地创建目录,本地创建目录自动
add
,但需要手动commit
。
usage: 1. mkdir PATH…
2. mkdir URL…
$ svn mkdir test1
A test1
$ svn mkdir -m "dir test2" http:/127.0.0.1:9988/svn/xxx1/svntest/test2
Committed revision 671.
$ svn up
Updating '.':
A test2
Updated to revision 671.
$ svn st
M test.txt
A test1
? test2.txt
revert
回复本地修改,用于解决本地冲突。放弃本地修改。
usage: revert PATH…
放弃本地修改
$ svn st
M test.txt
? test2.txt
$ svn revert test.txt
Reverted 'test.txt'
$ svn st
? test2.txt
放弃整个目录的修改
$ svn revert --recursive .
# 或
$ svn revert . --depth=infinity
copy
创建分支、打tag。发版
usage: copy SRC[@REV]… DST
简写:cp
$ svn copy http:/127.0.0.1:9988/svn/xxx1/svntest http:/127.0.0.1:9988/svn/xxx1/svntest1 -m "new branch"
Committed revision 673.
$ cd ../
$ svn co http:/127.0.0.1:9988/svn/xxx1/svntest1
A svntest1/test1
A svntest1/test2
A svntest1/a.ini
A svntest1/test.txt
A svntest1/b.ini
A svntest1/test
A svntest1/test/dir.txt
Checked out revision 673.
$ ll
total 0
drwxrwxr-x 1 frank frank 512 Feb 12 19:25 svntest
drwxrwxr-x 1 frank frank 512 Feb 12 19:31 svntest1
merge
根本版本或分支
这个命令很复杂,这里只将一个常用的分支合并。
将分支修改merge到主干
$ svn merge http:/127.0.0.1:9988/svn/xxx1/svntest1
--- Merging r673 through r674 into '.':
U test.txt
--- Recording mergeinfo for merge of r673 through r674 into '.':
U .
$ cat test.txt
11111
说明:
- 在主干目录执行
- URL填写分支的RUL
- 如果有冲突需要手动解决
changelist
这是一个不起眼,很少有人用的命令,不过在大项目里面,是分组协作的好帮手。
changelist
可以将功能相同的文件分组管理,然后对这个组进行统一操作。例如,可以把你负责的模块变成一组。
usage: 1. changelist CLNAME PATH…
2. changelist --remove PATH…
简写:cl
目前有多个文件发生了修改
$ svn st
M test/dir.txt
M test/rc.1
M test/rc.2
M test/rc.3
将rc相关功能的修改分组
$ svn cl rc test/rc.*
A [rc] test/rc.1
A [rc] test/rc.2
A [rc] test/rc.3
$ svn st
M test/dir.txt
--- Changelist 'rc':
M test/rc.1
M test/rc.2
M test/rc.3
按分组对比修改
$ svn di --cl rc
Index: test/rc.1
===================================================================
--- test/rc.1 (revision 679)
+++ test/rc.1 (working copy)
@@ -1 +1,3 @@
rc1
+rc1
+
Index: test/rc.2
===================================================================
--- test/rc.2 (revision 681)
+++ test/rc.2 (working copy)
@@ -1,2 +1,3 @@
rc2
rc2
+rc2
Index: test/rc.3
===================================================================
--- test/rc.3 (revision 681)
+++ test/rc.3 (working copy)
@@ -1,2 +1,3 @@
rc3
rc3
+rc3
按分组提交代码
$ svn ci -m "" --cl rc
Sending test/rc.1
Sending test/rc.2
Sending test/rc.3
Transmitting file data ...
Committed revision 682.
$ svn st
M test/dir.txt
cleanup
清理本地的lock。
SVN本地更新时,由于一些操作中断,如磁盘空间不够,用户取消等,可能会造成本地文件被锁定的情况。这时候无论你在执行SVN的更新、提交等子命令都会提示“**locked”的错误。这是需要使用该命令。
lock
锁定文件或目录,禁止其他用户修改。
usage: lock TARGET…
$ svn lock test.txt
'test.txt' locked by user 'xxx1'.
说明:
- 可以防止版本冲突,尤其是在修改文档的时候。比如office系列文档,subversion不把他们当做bin二进制文件处理不会自动merge。
--force
强制从其他用户手里偷锁。
unlock
是否锁
$ svn unlock test.txt
'test.txt' unlocked.
move
移动或重命名文件
usage: move SRC… DST
简写:mv, rename, ren
$ svn mv b.ini c.ini
A c.ini
D b.ini
$ svn st
D b.ini
A + c.ini
M test/dir.txt
$ ls
a.ini c.ini test test1 test2 test.txt
$ svn diff > diff.patch
$ svn revert . --depth=infinity
Reverted 'b.ini'
Reverted 'test/dir.txt'
Reverted 'c.ini'
$ ls
a.ini b.ini diff.patch test test1 test2 test.txt
patch
将补丁包导入
但我不推荐使用这个命令,可以直接使用patch
完成打补丁。
$ ls
a.ini b.ini test test1 test2 test.txt
$ svn st
M b.ini
$ svn diff > b.patch
$ cat b.patch
Index: b.ini
===================================================================
--- b.ini (revision 679)
+++ b.ini (working copy)
@@ -0,0 +1 @@
+1111
$ svn st
M b.ini
? b.patch
$ svn revert . --depth=infinity
Reverted 'b.ini'
$ svn st
? b.patch
$ patch -p0 < b.patch
patching file b.ini
$ svn st
M b.ini
? b.patch
说明:
svn revert . --depth=infinity
,递归回滚整个目录修改。-p0
从当前目录开始查找文件。
resolve
解决冲突,解决方式比较单一,要么用工作区的,要么服务器的,或是取个冲突最小的。——
强烈建议别用
$ svn resolve --accept=working a.ini
说明:
--accept
有三个参数可选:base
、working
、mine-conflict
resolved
告诉svn冲突我自己已经解决了.
之前说resolve并不好用,往往需要我们自己手动解决冲突,解决完之后需要告诉svn一声,resovled
就是用来通知svn冲突我自己解决了。
$ svn resolved a.ini
cat
查看指定版本文件的内容,这个命令还是很有用的。
usage: cat TARGET[@REV]…
$ svn cat -r 678 test.txt
11111
附录
命令列表
Available subcommands:
add
blame (praise, annotate, ann)
cat
changelist (cl)
checkout (co)
cleanup
commit (ci)
copy (cp)
delete (del, remove, rm)
diff (di)
export
help (?, h)
import
info
list (ls)
lock
log
merge
mergeinfo
mkdir
move (mv, rename, ren)
patch
propdel (pdel, pd)
propedit (pedit, pe)
propget (pget, pg)
proplist (plist, pl)
propset (pset, ps)
relocate
resolve
resolved
revert
status (stat, st)
switch (sw)
unlock
update (up)
upgrade
状态列表
The first seven columns in the output are each one character wide:
First column: Says if item was added, deleted, or otherwise changed
' ' no modifications
'A' Added
'C' Conflicted
'D' Deleted
'I' Ignored
'M' Modified
'R' Replaced
'X' an unversioned directory created by an externals definition
'?' item is not under version control
'!' item is missing (removed by non-svn command) or incomplete
'~' versioned item obstructed by some item of a different kind
Second column: Modifications of a file's or directory's properties
' ' no modifications
'C' Conflicted
'M' Modified
Third column: Whether the working copy directory is locked
' ' not locked
'L' locked
Fourth column: Scheduled commit will contain addition-with-history
' ' no history scheduled with commit
'+' history scheduled with commit
Fifth column: Whether the item is switched or a file external
' ' normal
'S' the item has a Switched URL relative to the parent
'X' a versioned file created by an eXternals definition
Sixth column: Repository lock token
(without -u)
' ' no lock token
'K' lock token present
(with -u)
' ' not locked in repository, no lock token
'K' locked in repository, lock toKen present
'O' locked in repository, lock token in some Other working copy
'T' locked in repository, lock token present but sTolen
'B' not locked in repository, lock token present but Broken
Seventh column: Whether the item is the victim of a tree conflict
' ' normal
'C' tree-Conflicted
If the item is a tree conflict victim, an additional line is printed
after the item's status line, explaining the nature of the conflict.
The out-of-date information appears in the ninth column (with -u):
'*' a newer revision exists on the server
' ' the working copy is up to date