一. SVN 常見屬于和檔案狀态
1. 常見術語
-
版本根目錄
上篇部落格中用到的/application/svndata
-
版本庫
repositoty 在伺服器端儲存着的項目中所有的檔案和操作記錄,一般一個項目對應一個版本庫
-
版本
Revision 版本庫中任意一次改動對應一個版本。
-
版本号
版本庫每次接受到送出操作後,會儲存資料,并将版本庫的版本号+1
-
檢出
用戶端第一次從版本庫中下載下傳項目,目前目錄下儲存——建立工作目錄。
-
工作副本
在用戶端儲存着的目前項目檔案的目錄(可能與版本庫内容不一緻)。
-
更新
用戶端從版本庫下載下傳最新版的項目檔案,并更新版本号
-
送出
将工作副本中更改後的項目送出的版本庫
2. 檔案狀态
檔案狀态是檔案對于工作副本而言的,不是對于SVN 伺服器版本庫。
-
無版本控制
在工作副本中新增的檔案,這個時候這個檔案是無版本控制狀态
-
增加
在共組副本中将無版本控制狀态的檔案,添加到版本控制系統中
-
修改
在工作副本中修改了檔案
-
正常
本地工作副本中的資料和svn 伺服器版本庫中的資料一緻的狀态
二. SVN 指令的使用
1. 檢視 svn 指令幫助
[root@Python ~]# svn --help
usage: svn <subcommand> [options] [args]
Subversion command-line client, version 1.6.11.
Type 'svn help <subcommand>' for help on a specific subcommand.
Type 'svn --version' to see the program version and RA modules
or 'svn --version --quiet' to see just the version number.
Most subcommands take file and/or directory arguments, recursing
on the directories. If no arguments are supplied to such a
command, it recurses on the current directory (inclusive) by default.
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)
propdel (pdel, pd)
propedit (pedit, pe)
propget (pget, pg)
proplist (plist, pl)
propset (pset, ps)
resolve
resolved
revert
status (stat, st)
switch (sw)
unlock
update (up)
Subversion is a tool for version control.
For additional information, see http://subversion.tigris.org/
[root@Python ~]# svn --help
usage: svn <subcommand> [options] [args]
Subversion command-line client, version 1.6.11.
Type 'svn help <subcommand>' for help on a specific subcommand.
Type 'svn --version' to see the program version and RA modules
or 'svn --version --quiet' to see just the version number.
Most subcommands take file and/or directory arguments, recursing
on the directories. If no arguments are supplied to such a
command, it recurses on the current directory (inclusive) by default.
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)
propdel (pdel, pd)
propedit (pedit, pe)
propget (pget, pg)
proplist (plist, pl)
propset (pset, ps)
resolve
resolved
revert
status (stat, st)
switch (sw)
unlock
update (up)
Subversion is a tool for version control.
For additional information, see http://subversion.tigris.org/
[root@Python ~]# svn info --help
info: Display information about a local or remote item.
usage: info [TARGET[@REV]...]
Print information about each TARGET (default: '.').
TARGET may be either a working-copy path or URL. If specified, REV
determines in which revision the target is first looked up.
Valid options:
-r [--revision] ARG : ARG (some commands also take ARG1:ARG2 range)
A revision argument can be one of:
NUMBER revision number
'{' DATE '}' revision at start of the date
'HEAD' latest in repository
'BASE' base rev of item's working copy
'COMMITTED' last commit at or before BASE
'PREV' revision just before COMMITTED
-R [--recursive] : descend recursively, same as --depth=infinity
--depth ARG : limit operation by depth ARG ('empty', 'files',
'immediates', or 'infinity')
--targets ARG : pass contents of file ARG as additional args
--incremental : give output suitable for concatenation
--xml : output in XML
--changelist ARG : operate only on members of changelist ARG
[aliases: --cl]
Global options:
--username ARG : specify a username ARG
--password ARG : specify a password ARG
--no-auth-cache : do not cache authentication tokens
--non-interactive : do no interactive prompting
--trust-server-cert : accept unknown SSL server certificates without
prompting (but only with '--non-interactive')
--config-dir ARG : read user configuration files from directory ARG
--config-option ARG : set user configuration option in the format:
FILE:SECTION:OPTION=[VALUE]
For example:
servers:global:http-library=serf
[root@Python ~]# svn info svn://192.168.10.1/sadoc
Path: sadoc
URL: svn://192.168.10.1/sadoc
Repository Root: svn://192.168.10.1/sadoc
Repository UUID: 1aa20afc-4318-4497-a077-c0f8c47884c4
Revision: 3
Node Kind: directory
Last Changed Author: admin
Last Changed Rev: 3
Last Changed Date: 2017-12-14 00:38:24 +0800 (Thu, 14 Dec 2017)
[root@Python ~]# svn info svn://192.168.10.1/sadoc -r 2
Path: sadoc
URL: svn://192.168.10.1/sadoc
Repository Root: svn://192.168.10.1/sadoc
Repository UUID: 1aa20afc-4318-4497-a077-c0f8c47884c4
Revision: 2
Node Kind: directory
Last Changed Author: admin
Last Changed Rev: 2
Last Changed Date: 2017-12-14 00:38:08 +0800 (Thu, 14 Dec 2017)
2. 導入 svn 原始目錄樹
svn import [PATH] URL -m "注釋資訊"
注意:svn import 指令必須接 -m 帶注釋資訊
将項目導入到 svn 版本庫中管理
[root@Python ~]# svn import --help
import: Commit an unversioned file or tree into the repository.
# 将未版本化的檔案或樹送出到存儲庫中。
usage: import [PATH] URL
Recursively commit a copy of PATH to URL.
If PATH is omitted '.' is assumed.
Parent directories are created as necessary in the repository.
If PATH is a directory, the contents of the directory are added
directly under URL.
Unversionable items such as device files and pipes are ignored
if --force is specified.
Valid options:
-q [--quiet] : print nothing, or only summary information
-N [--non-recursive] : obsolete; try --depth=files or --depth=immediates
# 表示不遞歸,則隻導入該目錄下的檔案,且不導入目錄
--depth ARG : limit operation by depth ARG ('empty', 'files',
'immediates', or 'infinity')
--auto-props : enable automatic properties
--force : force operation to run
--no-auto-props : disable automatic properties
-m [--message] ARG : specify log message ARG # 添加注釋資訊
-F [--file] ARG : read log message from file ARG
--force-log : force validity of log message source
--editor-cmd ARG : use ARG as external editor
--encoding ARG : treat value as being in charset encoding ARG
--with-revprop ARG : set revision property ARG in new revision
using the name[=value] format
--no-ignore : disregard default and svn:ignore property ignores
Global options:
--username ARG : specify a username ARG
--password ARG : specify a password ARG
--no-auth-cache : do not cache authentication tokens
--non-interactive : do no interactive prompting
--trust-server-cert : accept unknown SSL server certificates without
prompting (but only with '--non-interactive')
--config-dir ARG : read user configuration files from directory ARG
--config-option ARG : set user configuration option in the format:
FILE:SECTION:OPTION=[VALUE]
For example:
servers:global:http-library=serf
要使用 svn 管理的軟體項目通常會建3個目錄:
[root@Node1 ~]# mkdir -pv /data/oldboy/{trunk,branch,tags}
mkdir: created directory `/data/oldboy'
mkdir: created directory `/data/oldboy/trunk' # 主幹
mkdir: created directory `/data/oldboy/branch' # 分支
mkdir: created directory `/data/oldboy/tags' # 标簽
[root@Node1 ~]# svn import /data/oldboy/ file:///application/svndata/sadoc -m "import svntree"
# 本地導入
Adding /data/oldboy/trunk
Adding /data/oldboy/branch
Adding /data/oldboy/tags
Committed revision 2.
或者:
[root@Node1 ~]# svn import /data/oldboy/ svn://192.168.10.1/sadoc -m "import svntree"
# 遠端導入
Adding /data/oldboy/trunk
Adding /data/oldboy/branch
Adding /data/oldboy/tags
svn: File already exists: filesystem '/application/svndata/sadoc/db', transaction '2-2', path '/trunk'
3. svn checkout 和 svn export
3.1 svn checkout
checkout URL[@REV]... [PATH]
-r 指定版本參數
從版本庫中檢出工作副本
[root@Python ~]# svn checkout --help
checkout (co): Check out a working copy from a repository.
usage: checkout URL[@REV]... [PATH]
If specified, REV determines in which revision the URL is first
looked up.
If PATH is omitted, the basename of the URL will be used as
the destination. If multiple URLs are given each will be checked
out into a sub-directory of PATH, with the name of the sub-directory
being the basename of the URL.
If --force is used, unversioned obstructing paths in the working
copy destination do not automatically cause the check out to fail.
If the obstructing path is the same type (file or directory) as the
corresponding path in the repository it becomes versioned but its
contents are left 'as-is' in the working copy. This means that an
obstructing directory's unversioned children may also obstruct and
become versioned. For files, any content differences between the
obstruction and the repository are treated like a local modification
to the working copy. All properties from the repository are applied
to the obstructing path.
See also 'svn help update' for a list of possible characters
reporting the action taken.
Valid options:
-r [--revision] ARG : ARG (some commands also take ARG1:ARG2 range)
A revision argument can be one of:
NUMBER revision number
'{' DATE '}' revision at start of the date
'HEAD' latest in repository
'BASE' base rev of item's working copy
'COMMITTED' last commit at or before BASE
'PREV' revision just before COMMITTED
-q [--quiet] : print nothing, or only summary information
-N [--non-recursive] : obsolete; try --depth=files or --depth=immediates
--depth ARG : limit operation by depth ARG ('empty', 'files',
'immediates', or 'infinity')
--force : force operation to run
--ignore-externals : ignore externals definitions
Global options:
--username ARG : specify a username ARG
--password ARG : specify a password ARG
--no-auth-cache : do not cache authentication tokens
--non-interactive : do no interactive prompting
--trust-server-cert : accept unknown SSL server certificates without
prompting (but only with '--non-interactive')
--config-dir ARG : read user configuration files from directory ARG
--config-option ARG : set user configuration option in the format:
FILE:SECTION:OPTION=[VALUE]
For example:
servers:global:http-library=serf
[root@Python ~]# svn checkout svn://192.168.10.1/sadoc
A sadoc/trunk
A sadoc/V1
A sadoc/V1/1.txt
A sadoc/V2
A sadoc/v3
A sadoc/v5.txt
A sadoc/v6.txt
A sadoc/v7.log
A sadoc/branch
A sadoc/branch/v4
A sadoc/tags
Checked out revision 7.
注意: svn 指令預設會記住密碼
3.2 svn export
export [-r REV] URL[@PEGREV] [PATH]
export [-r REV] PATH1[@PEGREV] [PATH2]
從版本庫或工作副本導出資料
[root@Python ~]# svn export svn://192.168.10.1/sadoc test1
A test1
A test1/trunk
A test1/V1
A test1/V1/1.txt
A test1/V2
A test1/v3
A test1/v5.txt
A test1/v6.txt
A test1/v7.log
A test1/branch
A test1/branch/v4
A test1/tags
Exported revision 7.
[root@Python ~]# ls -a test1
. .. branch tags trunk V1 V2 v3 v5.txt v6.txt v7.log
[root@Python ~]# svn export test1 test2
svn: 'test1' is not a working copy
[root@Python ~]# svn export sadoc/ test2
Export complete.
[root@Python ~]# ls -a test2
. .. branch tags trunk V1 V2 v3 v5.txt v6.txt v7.log
3.3 總結
- checkout 和 export 用法一樣
- checkout 檢出的工作副本目錄中包含.svn 檔案夾是一個工作副本,而eport 不包含,隻是單純的導出項目檔案,不是工作副本,無版本控制。
- .svn 記錄着工作副本最後一次更新後的檔案狀态
- .svn 标記工作副本的一切變化
4. 檢視 svn 伺服器版本庫中的資料和資訊
4.1 list
list [TARGET[@REV]...]
-R 遞歸
列出版本庫或工作副本處于版本控制中的是以檔案。
[root@Python ~]# svn list svn://192.168.10.1/sadoc # 隻能檢視目錄下的檔案
V1/
V2/
branch/
tags/
trunk/
v3/
v5.txt
v6.txt
v7.log
[root@Python ~]# svn list svn://192.168.10.1/sadoc -v
7 admin Dec 14 00:56 ./
1 admin Dec 14 00:36 V1/
2 admin Dec 14 00:38 V2/
4 admin Dec 14 00:52 branch/
4 admin Dec 14 00:52 tags/
4 admin Dec 14 00:52 trunk/
3 admin Dec 14 00:38 v3/
5 admin 0 Dec 14 00:54 v5.txt
6 admin 0 Dec 14 00:55 v6.txt
7 admin 0 Dec 14 00:56 v7.log
[root@Python ~]# svn list sadoc -v
7 admin Dec 14 00:56 ./
1 admin Dec 14 00:36 V1/
2 admin Dec 14 00:38 V2/
4 admin Dec 14 00:52 branch/
4 admin Dec 14 00:52 tags/
4 admin Dec 14 00:52 trunk/
3 admin Dec 14 00:38 v3/
5 admin 0 Dec 14 00:54 v5.txt
6 admin 0 Dec 14 00:55 v6.txt
7 admin 0 Dec 14 00:56 v7.log
[root@Python ~]# svn list test1 -v
svn: 'test1' is not a working copy
[root@Python ~]# svn list -R sadoc/
V1/
V1/1.txt
V2/
V2/建立檔案夾/
branch/
branch/v4
t1/
t1/t2/
t1/t2/t3/
t1/t2/t3/test.md
tags/
trunk/
v3/
v3/v8.log
v8/
v9/
v9/v9.log
建立檔案夾/
建立文本文檔 (2).txt
建立文本文檔.txt
4.2 cat
cat TARGET[@REV]...
檢視版本庫或工作副本中的檔案的内容。
[root@Python ~]# svn cat sadoc/V1/1.txt
V1
[root@Python ~]# svn cat svn://192.168.10.1/sadoc/V1/1.txt
V1
4.3 info
info [TARGET[@REV]...]
檢視版本庫或工作副本檔案的詳細資訊
[root@Python sadoc]# svn info
Path: .
URL: svn://192.168.10.1/sadoc
Repository Root: svn://192.168.10.1/sadoc
Repository UUID: 1aa20afc-4318-4497-a077-c0f8c47884c4
Revision: 13
Node Kind: directory
Schedule: normal
Last Changed Author: xxj
Last Changed Rev: 13
Last Changed Date: 2017-12-14 02:18:14 +0800 (Thu, 14 Dec 2017)
[root@Python sadoc]# svn info /root/sadoc/
Path: /root/sadoc
URL: svn://192.168.10.1/sadoc
Repository Root: svn://192.168.10.1/sadoc
Repository UUID: 1aa20afc-4318-4497-a077-c0f8c47884c4
Revision: 13
Node Kind: directory
Schedule: normal
Last Changed Author: xxj
Last Changed Rev: 13
Last Changed Date: 2017-12-14 02:18:14 +0800 (Thu, 14 Dec 2017)
[root@Python sadoc]# svn info v3/v8.log
Path: v3/v8.log
Name: v8.log
URL: svn://192.168.10.1/sadoc/v3/v8.log
Repository Root: svn://192.168.10.1/sadoc
Repository UUID: 1aa20afc-4318-4497-a077-c0f8c47884c4
Revision: 35
Node Kind: file
Schedule: normal
Last Changed Author: admin
Last Changed Rev: 35
Last Changed Date: 2017-12-14 22:57:00 +0800 (Thu, 14 Dec 2017)
Text Last Updated: 2017-12-15 00:19:25 +0800 (Fri, 15 Dec 2017)
Checksum: d657c8dd2bf8f8497e315d72a75874eb
[root@Python sadoc]# svn info v3
Path: v3
URL: svn://192.168.10.1/sadoc/v3
Repository Root: svn://192.168.10.1/sadoc
Repository UUID: 1aa20afc-4318-4497-a077-c0f8c47884c4
Revision: 35
Node Kind: directory
Schedule: normal
Last Changed Author: admin
Last Changed Rev: 35
Last Changed Date: 2017-12-14 22:57:00 +0800 (Thu, 14 Dec 2017)
[root@Python sadoc]# svn info svn://192.168.10.1/sadoc/v3
Path: v3
URL: svn://192.168.10.1/sadoc/v3
Repository Root: svn://192.168.10.1/sadoc
Repository UUID: 1aa20afc-4318-4497-a077-c0f8c47884c4
Revision: 35
Node Kind: directory
Last Changed Author: admin
Last Changed Rev: 35
Last Changed Date: 2017-12-14 22:57:00 +0800 (Thu, 14 Dec 2017)
4.4 status
status [PATH...]
列出工作副本中的檔案的狀态
[root@Python ~]# svn status --help
status (stat, st): Print the status of working copy files and directories.
usage: status [PATH...]
' ' 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
4.5 log
檢視工作副本或版本庫送出日志(來自svn ci的-m參數)
[root@Python sadoc]# svn log --help
log: Show the log messages for a set of revision(s) and/or file(s).
usage: 1. log [PATH]
2. log URL[@REV] [PATH...]
Examples:
svn log
svn log foo.c
svn log http://www.example.com/repo/project/foo.c
svn log http://www.example.com/repo/project foo.c bar.c
[root@Python sadoc]# svn log
------------------------------------------------------------------------
r35 | admin | 2017-12-14 22:57:00 +0800 (Thu, 14 Dec 2017) | 1 line
------------------------------------------------------------------------
r34 | xxj | 2017-12-14 22:38:13 +0800 (Thu, 14 Dec 2017) | 1 line
------------------------------------------------------------------------
[root@Python sadoc]# svn log svn://192.168.10.1/sadoc/v3
------------------------------------------------------------------------
r35 | admin | 2017-12-14 22:57:00 +0800 (Thu, 14 Dec 2017) | 1 line
------------------------------------------------------------------------
r34 | xxj | 2017-12-14 22:38:13 +0800 (Thu, 14 Dec 2017) | 1 line
------------------------------------------------------------------------
r33 | xxj | 2017-12-14 22:36:55 +0800 (Thu, 14 Dec 2017) | 1 line
[root@Python sadoc]# svn log v3/v8.log
------------------------------------------------------------------------
r35 | admin | 2017-12-14 22:57:00 +0800 (Thu, 14 Dec 2017) | 1 lin
------------------------------------------------------------------------
r19 | xxj | 2017-12-14 04:03:08 +0800 (Thu, 14 Dec 2017) | 1 line
------------------------------------------------------------------------
r12 | xxj | 2017-12-14 02:17:31 +0800 (Thu, 14 Dec 2017) | 1 line
haha
------------------------------------------------------------------------
r8 | xxj | 2017-12-14 02:05:38 +0800 (Thu, 14 Dec 2017) | 1 line
add v8
------------------------------------------------------------------------
5. SVN 常用指令
5.1 add
add PATH...
* svn add --force*
表示目錄下所有檔案,--force 表示強制,如果不加--force,當目錄在版本控制下而該目錄下的檔案無版本控制,則添加不到。
添加到版本控制
[root@Python sadoc]# mkdir v9
[root@Python sadoc]# touch v9/v9.log
[root@Python sadoc]# svn add /root/sadoc
svn: '/root' is not a working copy
[root@Python sadoc]# svn add /root/sadoc/v9
A /root/sadoc/v9
A /root/sadoc/v9/v9.log
[root@Python sadoc]# svn st
A v3/v8.log
A v9
A v9/v9.log
5.2 commit
commit [PATH...] -m "注釋資訊"
将工作副本中的修改送出到svn伺服器版本庫(版本号+1)
[root@Python sadoc]# svn st
A v3/v8.log
A v9
A v9/v9.log
[root@Python sadoc]# svn up
At revision 7.
[root@Python sadoc]# svn ci -m "add v8"
Adding v3/v8.log
Adding v9
Adding v9/v9.log
Transmitting file data ..
Committed revision 8.
[root@Python sadoc]# svn st
[root@Python sadoc]#
5.3 update
update [PATH...]
更新工作副本(預設更新的最新版)
[root@Python sadoc]# svn update --help
update (up): Bring changes from the repository into the working copy.
usage: update [PATH...]
A Added
D Deleted
U Updated
C Conflict
G Merged
E Existed
[root@Python sadoc]# svn up
D v5.txt
A V2/建立檔案夾
U v7.log
Updated to revision 9.
5.4 delete
1. delete PATH...
2. delete URL...
從版本庫中删除檔案或目錄
[root@Python sadoc]# svn st
[root@Python sadoc]# ls
branch tags trunk V1 V2 v3 v7.log v9 建立檔案夾
[root@Python sadoc]# svn del v7.log
D v7.log
[root@Python sadoc]# svn st
D v7.log
[root@Python sadoc]# svn up
At revision 15.
[root@Python sadoc]# svn st
D v7.log
[root@Python sadoc]# svn ci -m "D v7"
Deleting v7.log
Committed revision 16.
[root@Python sadoc]# svn st
5.5 diff
版本差異比較
[root@Python sadoc]# svn diff --help
diff (di): Display the differences between two revisions or paths.
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]
[root@Python sadoc]# vim v3/v8.log
[root@Python sadoc]# svn st
M v3/v8.log
[root@Python sadoc]# svn diff
# 目前版本和工作副本的差異
Index: v3/v8.log
===================================================================
--- v3/v8.log (revision 18)
+++ v3/v8.log (working copy)
@@ -1,3 +1,4 @@
12
14
-xj
+xxj
+111111111111111111111
[root@Python sadoc]# svn ci -m ""
Sending v3/v8.log
Transmitting file data .
Committed revision 19.
[root@Python sadoc]# svn diff
[root@Python sadoc]# svn diff -r 10
# 某個曆史版本與工作副本的差異
Index: v3/v8.log
===================================================================
--- v3/v8.log (revision 10)
+++ v3/v8.log (working copy)
@@ -0,0 +1,4 @@
+12
+14
+xxj
+111111111111111111111
Index: v7.log
===================================================================
--- v7.log (revision 10)
+++ v7.log (working copy)
@@ -1,2 +0,0 @@
-7777
-10
[root@Python sadoc]# svn diff -r 10:11
# 兩個曆史版本間的差異
Index: v7.log
===================================================================
--- v7.log (revision 10)
+++ v7.log (revision 11)
@@ -1,2 +1,3 @@
7777
10
+11
5.6 mkdir
建立目錄并增加到版本控制
[root@Python sadoc]# svn mkdir --help
mkdir: Create a new directory under version control.
usage: 1. mkdir PATH...
2. mkdir URL...
[root@Python sadoc]# svn mkdir xxj
A xxj
5.7 revert
* svn revert [-R] [filename|]**
工作副本還原,将工作副本還原成未送出前的狀态
[root@Python ~]# svn revert --help
revert: Restore pristine working copy file (undo most local edits).
usage: revert PATH...
Note: this subcommand does not require network access, and resolves
any conflicted states. However, it does not restore removed directories.
Valid options:
--targets ARG : pass contents of file ARG as additional args
-R [--recursive] : descend recursively, same as --depth=infinity
[root@Python sadoc]# vim t1/t2/t3/test.md
[root@Python sadoc]# svn st
M t1/t2/t3/test.md
[root@Python sadoc]# svn revert -R t1
Reverted 't1/t2/t3/test.md'
三. 沖突
1. 沖突
在項目中,基本不可避免多個人同時參與一個項目,是以就可能會出現多個人同時修改一個檔案的情況,就不可避免的會出現沖突。svn已經很聰明了,如果你和别人對于同一個檔案的修改之間不存在重疊(比如你在檔案最開始增加了一行,而你同僚在檔案的結尾出增加了一行(好像隻對純文字文檔)),svn會自動将你們的修改進行合并,然而意外總是會發生,而且超出了svn的處理範圍,隻好采用人工智能(手工)來進行合并了。
1.1 檔案沖突
當兩名或更多開發人員修改了同一個檔案中相鄰或相同的行時就會發生檔案沖突。由于 Subversion 不知道你的項目的具體情況,它把解決沖突的工作留給了開發人員。
1.2 樹沖突
當一名開發人員移動、重命名、删除一個檔案或檔案夾,而另一名開發人員也對它們進行了移動、重命名、删除或者僅僅是修改時就會發生樹沖突。非檔案沖突就是樹沖突
2. 沖突産生的條件
- 沖突常出現于工作副本長時間未更新時
- 更新到的資料與工作副本的修改正好在同一處
3. 如何盡可能的避免沖突
經常update
4. 如何解決沖突
文本沖突
[root@Python sadoc]# svn resolve --help
resolve: Resolve conflicts on working copy files or directories.
usage: resolve --accept=ARG [PATH...]
Note: the --accept option is currently required.
Valid options:
--targets ARG : pass contents of file ARG as additional args
-R [--recursive] : descend recursively, same as --depth=infinity
--depth ARG : limit operation by depth ARG ('empty', 'files',
'immediates', or 'infinity')
-q [--quiet] : print nothing, or only summary information
--accept ARG : specify automatic conflict resolution source
('base', 'working', 'mine-conflict',
'theirs-conflict', 'mine-full', 'theirs-full')
[root@Python sadoc]# svn resolved --help
resolved: Remove 'conflicted' state on working copy files or directories.
usage: resolved PATH...
C:\workspace\test>svn up
Conflict discovered in 'test.txt'.
Select: (p) postpone, (df) diff-full, (e) edit,
(mc) mine-conflict, (tc) theirs-conflict,
(s) show all options:
svn detects that theres a conflict here and require you to take some kind of action.
If you type 's' here you will get a list of the commands and meaning
如果你輸入s選項,則會列出所有svn解決沖突的選項,如下所示:
(e) edit - change merged file in an editor #直接進入編輯
(df) diff-full - show all changes made to merged file #顯示更改至目标檔案的所有變化
(r) resolved - accept merged version of file
(dc) display-conflict - show all conflicts (ignoring merged version) #顯示所有沖突
(mc) mine-conflict - accept my version for all conflicts (same) #沖突以本地為準
(tc) theirs-conflict - accept their version for all conflicts (same) #沖突以伺服器為準
(mf) mine-full - accept my version of entire file (even non-conflicts)#完全以本地為準
(tf) theirs-full - accept their version of entire file (same) #完全以伺服器為準
(p) postpone - mark the conflict to be resolved later #标記沖突,稍後解決
(l) launch - launch external tool to resolve conflict
(s) show all - show this list
【選擇處理方式一:df】
If you type 'df' it will show you a all the conflicts in the following format
選擇選項df,則會按如下格式顯示所有沖突
Select: (p) postpone, (df) diff-full, (e) edit,
(mc) mine-conflict, (tc) theirs-conflict,
(s) show all options: df
--- .svn/text-base/test.txt.svn-base Tue Aug 10 10:59:38 2010
+++ .svn/tmp/test.txt.2.tmp Tue Aug 10 11:33:24 2010
@@ -1 +1,3 @@
-test
\ No newline at end of file
+<<<<<<< .mine +test User2 making conflict======= +User1 is making a conflict test>>>>>>> .r3
'e' option will open the conflicted file in the text editor that you configured for svn to use. In this case it will show
<<<<<<< .mine test User2 making conflict======= User1 is making a conflict test>>>>>>> .r3
You can resolve the conflict here by changing the text to what you desire.
For example:
你可以解決沖突通過改變檔案内容,例如vim test.txt
User1 is making a conflict test User2 making conflict
save your changes and exit your text editor and it will give you the conflict options again. Now if you use the 'r' it will mark the file is merged with a 'G'. A status of 'G' means there was a conflict and it has been resolved.
儲存更改,又出現剛才的選項。此時你使用r選項,則會合并檔案。如下所示:
Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
(mc) mine-conflict, (tc) theirs-conflict,
(s) show all options: e
Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
(mc) mine-conflict, (tc) theirs-conflict,
(s) show all options: r
G test.txt
Updated to revision 3.
you can now check the status with svn status. You see that test.txt is marked as 'M' all thats left to do is commit.
檢查svn狀态,你會發現檔案test.txt前面已變成M
C:\workspace\test2>svn st
M test.txt
C:\workspace\test2>svn ci -m "conflict resolved"
Sending test.txt
Transmitting file data .
Committed revision 4.
【選擇處理方式二:p】
Sometimes the conflicts are a bit more extensive and it requires more time or better tools to resolve the conflict in these cases you can chose 'p' to postpone the resolution.
有時,沖突會複雜一些,可能需要借助其他工具才能解決,這時你可以使用選項p
Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
(mc) mine-conflict, (tc) theirs-conflict,
(s) show all options: p
C test.txt
Updated to revision 3.
Summary of conflicts:
Text conflicts: 1
Now if you look in your directory you will see that svn has created a few extra files for you.
此時,檢視目前檔案夾下,出現了如下幾個檔案
08/10/2010 11:44 AM 94 test.txt
08/10/2010 11:44 AM 26 test.txt.mine
08/10/2010 11:44 AM 27 test.txt.r2
08/10/2010 11:44 AM 31 test.txt.r3
The test.txt file is now a file with both User2 and User1′s changes but marked.
檔案test.txt包含了使用者1和使用者2的更改。
<<<<<<< .mine test User2 making conflict======= User1 am making a conflict test>>>>>>> .r3
test.txt.mine is User2′s copy.
檔案.txt.mine儲存了使用者2的内容
test User2 making conflict
test.txt.r2 is the original base copy
檔案.txt.r2是未沖突前的内容
test
test.txt.r3 is the copy User1 commited
檔案.txt.r3儲存了使用者1的内容
User1 is making a conflict test
At this point you can choose your favorite merge tools to merge the differences in a file.
這種情況下,你可以選擇自己喜歡的對比工具,檢視差别。
I suggest merging the differences into test.txt and the do a
我建議和并不同至檔案test.txt中,如果如下指令:
C:\workspace\test>svn resolve --accept working test.txt
Resolved conflicted state of 'test.txt'
You can also use any of the other files if you wanted to and just pass resolve –accept a different argument. Here are the valid arguments
當然,你也可以使用其他檔案,使用resolve -accept 加其他參數,共6個
(1)#svn resolve –accept base
Choose the file that was the BASE revision before you updated your working copy. That is, the file that you checked out before you made your latest edits.
使用1.txt.r2作為最後送出的版本
(2)#svn resolve –accept working
Assuming that you've manually handled the conflict resolution, choose the version of the file as it currently stands in your working copy.
使用目前拷貝即test.txt作為最後送出的版本
(3)#svn resolve –accept mine-full
Resolve all conflicted files with copies of the files as they stood immediately before you ran svn update.
使用test.txt.mine作為最後送出的版本
(4)#svn resolve –accept theirs-full
Resolve all conflicted files with copies of the files that were fetched from the server when you ran svn update.
使用test.txt.r3作為最後送出的版本
(5)#svn resolve –accept mine-conflict
沖突的部分以本地修改為準
(6)#svn resolve –accept theirs-conflict
沖突的部分以伺服器端修改為準
執行一下:svn resolved test.txt。
Now you are ready to commit.
然後送出
C:\workspace\test>svn ci -m "conflict resolved"
Sending test.txt
Transmitting file data .
Committed revision 4.
四. 鎖定與解鎖
svn lock
鎖定檔案,防止其它成員對檔案進行送出
svn unlock
解鎖檔案
svn ci 送出後會自動解鎖,如果不想自動解鎖則使用--no-unlock : don'
[root@Python sadoc]# svn lock --help
lock: Lock working copy paths or URLs in the repository, so that
no other user can commit changes to them.
usage: lock TARGET...
Use --force to steal the lock from another user or working copy.
[root@Python sadoc]# svn unlock --help
unlock: Unlock working copy paths or URLs.
usage: unlock TARGET...
Use --force to break the lock.
[root@Python sadoc]# svn lock v3/v8.log
'v8.log' locked by user 'xxj'.
[root@Python sadoc]# svn st
K v3/v8.log
[root@Python sadoc]# svn unlock v3/v8.log
'v8.log' unlocked.
[root@Python sadoc]# svn st
五. copy
copy SRC[@REV]... DST
svn copy --help
copy (cp): Duplicate something in working copy or repository, remembering
history.
usage: copy SRC[@REV]... DST
When copying multiple sources, they will be added as children of DST,
which must be a directory.
SRC and DST can each be either a working copy (WC) path or URL:
WC -> WC: copy and schedule for addition (with history)
WC -> URL: immediately commit a copy of WC to URL
URL -> WC: check out URL into WC, schedule for addition
URL -> URL: complete server-side copy; used to branch and tag
All the SRCs must be of the same type.
copy 分四大類:
1. 工作副本 -->工作副本
[root@Python sadoc]# svn copy v3/v8.log copy.log
A copy.log
[root@Python sadoc]# svn st
A + copy.log
[root@Python sadoc]# cp v3/v8.log xxj.log
[root@Python sadoc]# svn st
? xxj.log
A + copy.log
[root@Python sadoc]# svn add xxj.log
A xxj.log
[root@Python sadoc]# svn st
A xxj.log
A + copy.log
[root@Python sadoc]# svn cp -r 30 v3/v8.log copy2.log
A copy2.log
[root@Python sadoc]# svn st
A xxj.log
A + copy.log
A + copy2.log
2. 工作副本 -->版本庫
不支援跨庫
[root@Python sadoc]# svn cp v3/v8.log svn://192.168.10.1/sadoc
svn: No repository found in 'svn://192.168.10.1'
[root@Python sadoc]# svn cp v3/v8.log svn://192.168.10.1/sadoc/target.html
svn: Could not use external editor to fetch log message; consider setting the $SVN_EDITOR environment variable or using the --message (-m) or --file (-F) options
svn: None of the environment variables SVN_EDITOR, VISUAL or EDITOR are set, and no 'editor-cmd' run-time configuration option was found
[root@Python sadoc]# svn cp v3/v8.log svn://192.168.10.1/sadoc/target.html -m ""
Committed revision 38.
從工作副本copy到版本庫就直接送出了(跳過了本地工作副本)
3. 版本庫 -->工作副本
支援跨庫copy
記住不允許跨庫送出
4. 版本庫-->版本庫
就是建立分支
svn cp svn://192.168.10.1/sadoc/ svn://192.168.10.1/sadoc/trunk -m "mkdir trunk"
Committed revision 52.
# 建立主幹版本
# svn://192.168.10.1/sadoc/ 這裡帶/是複制該目錄下的所有檔案,不帶就是複制該目錄
[root@Node1 sadoc]# svn cp svn://192.168.10.1/sadoc/trunk svn://192.168.10.1/sadoc/branch -m "mkdir branch"
Committed revision 53.
# 建立分支版本
六. hooks
1. hooks簡介
hooks 鈎子
何為鈎子?
可以了解為觸發器,當執行某些特定操作時觸發執行預先設定好的任務。
SVN的hooks模版功能介紹
start-commit 送出前觸發事務
pre-commit 送出完成前觸發事務,在Subversion transaction完畢之後,在送出之前,執行該腳本
post-commit 送出完成時觸發事務;在送出完成,成功建立版本之後執行該鈎子,送出已經完成,不可更改,是以本腳本的傳回值被忽略
post-lock 對檔案進行加鎖操作之後執行該腳本
post-revprop-change 在修改revision 屬性之後,執行該腳本,因為修改稿已經完成,不可更改,是以本腳本的傳回值被忽略(不過實際上的實作似乎是該腳本的正确執行與否英雄屬性修改)
[root@Node1 sadoc]# ls
conf db format hooks locks README.txt
[root@Node1 sadoc]# ls hooks/
post-commit.tmpl post-unlock.tmpl pre-revprop-change.tmpl
post-lock.tmpl pre-commit.tmpl pre-unlock.tmpl
post-revprop-change.tmpl pre-lock.tmpl start-commit.tmpl
# hooks目錄下有很多鈎子模版檔案(其實就是shell腳本), 隻需要複制模版去掉.tmpl字尾就可以生效使用了
svn 鈎子在生産中的應用舉例:
- 限制上傳檔案擴充名及大小
- svn更新自動周知,MSN,郵件或短信周知
- SVN更新觸發實時rsync推送
例:
/usr/bin/svn up --username admin --password admin /data/www && /usr/bin/rsync -az --delete /data/www /tmp/
寫鈎子腳本的一些注意事項:
- 鈎子腳本的權限運作svn執行
- 寫鈎子腳本時要使用絕對路徑,因為svn考慮安全問題,不會調用系統環境變量,所有發現手動執行post-commit是沒有問題,但svn自動執行也可能會無法執行。
- 盡可能定義環境變量,盡可能加上使用者和密碼,如果隻是手動一樣會更新,但自動觸發可能會失敗。
七. 版本庫相關操作
1. 版本庫精簡
一個版本庫使用時間長了,版本号越來越大,版本庫占用的空間越來越多,到了一定時間我們可能需要對版本庫進行精簡,把早些時候的版本丢棄,來達到瘦身的目的。
1.1 停止svnserve服務
進行版本庫精簡需要先停止svn服務,防止此時有人送出發生錯誤
[root@Node1 hooks]# pkill svnserve
1.2 備份需要的版本資料
需要把想要保留下的版本資料備份出來
[root@Node1 hooks]# svnadmin dump --help
dump: usage: svnadmin dump REPOS_PATH [-r LOWER[:UPPER] [--incremental]]
Dump the contents of filesystem to stdout in a 'dumpfile'
portable format, sending feedback to stderr. Dump revisions
LOWER rev through UPPER rev. If no revisions are given, dump all
revision trees. If only LOWER is given, dump that one revision tree.
If --incremental is passed, the first revision dumped will describe
only the paths changed in that revision; otherwise it will describe
every path present in the repository as of that revision. (In either
case, the second and subsequent revisions, if any, describe only paths
changed in those revisions.)
# 注意這裡使用的版本庫檔案系統路徑(就是資料庫的路徑)
Valid options:
-r [--revision] ARG : specify revision number ARG (or X:Y range)
--incremental : dump incrementally
--deltas : use deltas in dump output
-q [--quiet] : no progress (only errors) to stderr
# 備份版本号30--56的資料
[root@Node1 hooks]# svnadmin dump /application/svndata/sadoc/ -r 30:56 > /tmp/sadoc.repo
#
* Dumped revision 30.
* Dumped revision 31.
* Dumped revision 32.
* Dumped revision 33.
* Dumped revision 34.
* Dumped revision 35.
* Dumped revision 36.
* Dumped revision 37.
* Dumped revision 38.
* Dumped revision 39.
* Dumped revision 40.
* Dumped revision 41.
* Dumped revision 42.
* Dumped revision 43.
* Dumped revision 44.
* Dumped revision 45.
* Dumped revision 46.
* Dumped revision 47.
* Dumped revision 48.
* Dumped revision 49.
* Dumped revision 50.
* Dumped revision 51.
* Dumped revision 52.
* Dumped revision 53.
* Dumped revision 54.
* Dumped revision 55.
* Dumped revision 56.
1.3 建立新的版本庫并導入備份資料
[root@Node1 svndata]# svdadmin create newsadoc
-bash: svdadmin: command not found
[root@Node1 svndata]#
[root@Node1 svndata]# svnadmin create newsadoc
[root@Node1 svndata]# ls
newsadoc sadoc t1 t2
[root@Node1 svndata]# svnadmin load newsadoc/ < /tmp/sadoc.repo
<<< Started new transaction, based on original revision 30
* adding path : 建立檔案夾 ... done.
* adding path : 建立文本文檔.txt ... done.
* adding path : trunk ... done.
* adding path : t1 ... done.
* adding path : t1/t2 ... done.
* adding path : t1/t2/t3 ... done.
* adding path : t1/t2/t3/test.md ... done.
* adding path : 建立文本文檔 (2).txt ... done.
* adding path : V1 ... done.
* adding path : V1/1.txt ... done.
* adding path : V2 ... done.
* adding path : V2/建立檔案夾 ... done.
* adding path : v3 ... done.
* adding path : v3/v8.log ... done.
* adding path : branch ... done.
* adding path : branch/v4 ... done.
* adding path : v8 ... done.
* adding path : tags ... done.
* adding path : v9 ... done.
* adding path : v9/v9.log ... done.
------- Committed new rev 1 (loaded from original rev 30) >>>
<<< Started new transaction, based on original revision 31
* deleting path : V1/1.txt ... done.
------- Committed new rev 2 (loaded from original rev 31) >>>
<<< Started new transaction, based on original revision 55
* adding path : xx ... done.
------- Committed new rev 26 (loaded from original rev 55) >>>
<<< Started new transaction, based on original revision 56
* editing path : copy.log ... done.
------- Committed new rev 27 (loaded from original rev 56) >>>
1.4 複制配置檔案并啟動svnserve
[root@Node1 svndata]# cp -a sadoc/conf newsadoc/
[root@Python ~]# svn co svn://192.168.10.1/newsadoc
A newsadoc/建立檔案夾
A newsadoc/xj
A newsadoc/t1
A newsadoc/trunk/v9/v9.log
Checked out revision 27.
[root@Python ~]# svn info newsadoc
Path: newsadoc
URL: svn://192.168.10.1/newsadoc
Repository Root: svn://192.168.10.1/newsadoc
Repository UUID: 1aa20afc-4318-4497-a077-c0f8c47884c4
Revision: 27
Node Kind: directory
Schedule: normal
Last Changed Author: xxj
Last Changed Rev: 27
Last Changed Date: 2017-12-15 20:34:36 +0800 (Fri, 15 Dec 2017)
[root@Python ~]# svn log newsadoc
------------------------------------------------------------------------
r27 | xxj | 2017-12-15 20:34:36 +0800 (Fri, 15 Dec 2017) | 1 line
------------------------------------------------------------------------
r1 | xxj | 2017-12-14 22:29:46 +0800 (Thu, 14 Dec 2017) | 1 line
------------------------------------------------------------------------
2. 版本庫遷移與switch重定向
- 停止svnserve服務
- 把版本庫檔案系統目錄(資料庫)拷貝到新伺服器上
- 在新伺服器上運作svnserve
[root@Python newsadoc]# svn switch --help
switch (sw): Update the working copy to a different URL.
usage: 1. switch URL[@PEGREV] [PATH]
2. switch --relocate FROM TO [PATH...]
[root@Python newsadoc]# svn up
svn: No repository found in 'svn://192.168.10.1/newsadoc'
[root@Python newsadoc]# svn sw svn://192.168.10.1/sanew .
svn: 'svn://192.168.10.1/newsadoc'
is not the same repository as
'svn://192.168.10.1/sanew'
[root@Python newsadoc]# svn sw --relocate svn://192.168.10.1/newsadoc svn://192.168.10.1/sanew