【SVN】2. SVN 基本操作

一. 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 鉤子在生產中的應用舉例:

  1. 限制上傳文件擴展名及大小
  2. svn更新自動周知,MSN,郵件或短信周知
  3. SVN更新觸發實時rsync推送

例:


/usr/bin/svn up --username admin --password admin /data/www && /usr/bin/rsync -az --delete /data/www /tmp/

寫鉤子腳本的一些注意事項:

  1. 鉤子腳本的權限運行svn執行
  2. 寫鉤子腳本時要使用絕對路徑,因爲svn考慮安全問題,不會調用系統環境變量,所有發現手動執行post-commit是沒有問題,但svn自動執行也可能會無法執行。
  3. 儘可能定義環境變量,儘可能加上用戶和密碼,如果只是手動一樣會更新,但自動觸發可能會失敗。

七. 版本庫相關操作

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
------------------------------------------------------------------------

注意:版本庫精簡後舊的工作副本也不能使用了,需要重新co一份工作副本,其實就是複製了版本庫

2. 版本庫遷移與switch重定向

  版本庫遷移一般發生在更換svn服務器時,有2種方法,第一種就是上節所學到的用svnadmin dump 備份整個版本庫,再導入到新鍵的版本庫中。第二種方法就很簡單粗暴:複製整個版本庫到新服務器上:

  1. 停止svnserve服務
  2. 把版本庫文件系統目錄(數據庫)拷貝到新服務器上
  3. 在新服務器上運行svnserve

  版本庫遷移後,客戶端工作副本中記錄的原svn服務器的URL就失效了,就需重新定位到新svn服務器,這個操作就稱爲重定向

[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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章