SVN命令 二

我打算一口氣講完SVN的使用,所以,在看之前呢,請先深深的吸一口氣(怎麼聽着像黑龍公主),當然吸完後還是要呼出來的。不要憋着了。

 

我們可能希望一來就直接操作。列出一堆命令。詳細的命令參數等信息,我們都可以加入 --help 選項獲取,下面不會詳細介紹。除非必要。現在先看下面的例子:

$svn --help 

usage: svn <subcommand> [options] [args]

Subversion command-line client, version 1.6.12.

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/

好了,什麼都出來了。一大堆信息。慢慢讀吧。可是這樣的方式,對我們使用SVN並無指導意義。什麼時候用什麼命令? 下面就來說一下SVN的基本使用,在此之前,還有兩個重要的東西需要理解。

SVN 除了可以讓你追溯歷史,還有一個重要的功能,便是多人協作。我們要解決的問題不僅僅是可以從歷史中恢復。還有如果多人同時修改一個文件,那麼該以誰的爲主呢?

所以在SVN中,我們有兩種使用模式:

Lock-Modify-Unlock

簡單的說就是,給需要修改的文件加鎖,然後修改,然後解鎖。

這是一個很好的辦法。但是如果一個文件被鎖住了,那麼其他人就不能修改了。而此時如果是我在修改文件頭,而你需要修改文件末尾的話,你也只能等我修改完。這樣是很浪費你的時間的。所以我們又有另外一種模式。

Copy-Modify-Merge

這是一種很高級的模式,從庫中拷貝一份,修改,然後根據拷貝的和庫中的不同,在合併。爲什麼說高級呢,因爲合併是一個很複雜的過程。很可能失敗。但是這種方法卻儘可能使大家不受影響。例如你和我同時修改一個文件,我改文件頭,你改文件尾,然後一提交,就給合成一份了。不會互相打擾。事實上問題比這複雜的多。

好了,說了這麼多廢話。我們可以正式開始了。

雖然一般情況,我們是不用自己去創建一個SVN庫的,現在爲了說明流暢,我們從創建一個庫開始。

$svnadmin create  /var/idp/repos

於是我們創建了一個SVN庫。到下面看看

$ls /var/idp/repos

conf  db  format  hooks  locks  README.txt

我們的庫就創建好了。這裏不多說, svnadmin是一個高級命令,我們基本用不到。

導入需要管理的文件:

$svn import /home/madic/code file:///var/idp/repos -m "init code"

Adding         /home/madic/code/signo

Adding         /home/madic/code/signo/sigset.c

Adding  (bin)  /home/madic/code/signo/wait

Adding         /home/madic/code/signo/wait.c

Committed revision 1.

這裏版本變爲1,初始版本爲0。  每次對庫的操作改變,都會產生一個新的版本。版本是我們追溯歷史的一個索引。在版本管理中非常重要。當前庫中最新的版本可以用HEAD表示。HEAD版也就是庫中最新版本。

我們把 /home/madic/code 文件下的文件目錄都導入了svn庫,從此,他們就被時光機管理,數據永不丟失(當然你幹掉時光機,數據還是會丟失的)。

注意 (bin) 表示這是一個二進制文件,非文本文件。

除了import 外,我們還可以用 svn add 添加文件。

使用list命令查看庫中文件

$svn  list  file:///var/idp/repos

signo/

signo/sigset.c

signo/wait

signo/wait.c

現在,我們開始工作了。那麼,就使用 CMC(Copy-Modify-Merge)模式吧。

如何創建一個Working Copy 呢?看:

$svn checkout file:///var/idp/repos  /home/madic/code_svn

A    /home/madic/code_svn/signo

A    /home/madic/code_svn/signo/sigset.c

A    /home/madic/code_svn/signo/wait

A    /home/madic/code_svn/signo/wait.c

Checked out revision 1.

恭喜我們現在擁有一個Working Copy了,你就在這個WorkingCopy中折騰吧,只要不提交,那麼對庫來說就沒有任何影響。就算你用了 rm 不小心刪除了某個文件,不用着急。使用update便可以找回。

$svn update 

svn update

Restored 'main.c'

At revision 1.

這裏,我們刪掉 main.c 然後到WC 下,執行 svn update 命令,就找回main.c了。

Working Copy 目錄中,Subversion如何知道文件的情況呢,其實這些都是 .svn的功勞。每個SVN管理的WC中,都會有一個隱藏的文件夾,.svn 

$ls -la .svn

drwxr-xr-x  6 madic madic 4096 2011-07-26 11:00 .svn

如果不小心誤刪除,也可以用svn update恢復。

接下來,我們開始正常的編輯文件。編輯之前,已定要使用svn update 來確保你編輯的文件是最新的。如果不是最新的,那麼這個文件就是 Out-of-date了,此時你的編輯就不能被提交到庫中。編輯時,你不必使用svn的命令了。你可以用任何編輯器編輯文件。當你編輯完成後保存。

$svn status -q

M       readme.txt

這個M表示此文件被修改了。於是我們需要把她提交到庫,這樣別人才能看到我修改的東西。

$svn commit -m "我修改了文件內容" readme.txt

svn commit -m "modify" readme.txt

Sending        readme.txt

Transmitting file data .

Committed revision 8.

文件被提交,版本更新到8.

這樣,我們就完成了一個最基本的SVN操作流程。也許如果沒有什麼大事,我們就到此結束了。難道還有什麼問題嗎?

上面提到,我們在修改的同時,可能別人也在修改。所以要儘量在每次修改的時候,保持我們的WC和庫中的是同步的,也就是最新的。我們使用svn update來使自己的working copy是最新的。我們也可以用一個新的命令來看WC的狀態。

$svn status -u -v readme.txt

M                8        8  madic        readme.txt

M     *          8        3  madic        foo.c

我們看到readme.txt 目前是M(modify)狀態,說明此文件被改了。當前版本和最新版本都是,用戶是madic

foo.c 多了個星號,這表明foo.c 已經out-of-date 了。也就是說,我們在修改的版本,已經不是最新的了。在我們修改的時候,已經有人提交了新的版本。

除了 M表示修改,還有 U表示更新,D表示刪除,表示新增, C表示衝突。

有時候有兩個MM,此時並非表示美眉,而是文件的內容和屬性都被改變了。

同樣UU表示屬性和內容都更新了。

所以,在我們提交以後,並非就結束了,此時,我們需要查看一下狀態。如果有文件處於C狀態,那麼說明我們遇到麻煩了。因爲C表示衝突了,一定是某個人和我們在改同一個地方。

這時,最好的辦法是直接找到和我們衝突的修改人。然後溝通吧。是你死還是我亡。衝突實際上是在svn update的時候發生的。由於我編輯的太久了,你已經提交了一個新版本,我提交的時候,提示 out-of-date了,於是我svn update,衝突出現:

$ svn update

Conflict discovered in 'readme.txt'.

Select: (p) postpone, (df) diff-full, (e) edit,

        (mc) mine-conflict, (tc) theirs-conflict,

        (s) show all options:

這時幾個選擇出現了,postpone 的意思是暫時推後處理,我可能要和那個和我衝突的傢伙商量一番。 diff-full,則是比比看,到底什麼地方衝突了。edit,修改衝突合併的文件。 mc,這個霸道,直接用我的。 tc , 底氣不足,還是用別人修改的吧。我們一切三思而後行,所以選擇了p,然後在看看文件目錄下有什麼。

多了三個文件:

readme.txt.mine  readme.txt.r9  readme.txt  readme.txt.r8

我們來說說這三個文件:readme.txt.mine 後最 mine是本地最新的。

readme.txt.r9 很明顯,是版本9的,這個版本正式庫中最新的版本。

readme.txt.r8  這個版本是庫中最新的版本的前一版本。

我們來看一下,現在的readme.txt

$cat readme.txt

<<<<<<< .mine

hi

=======

hello

>>>>>>> .r9

很明顯,我的版本中是hi ,而r9 的是hello

好吧,我明白了。現在假設我們很明白,或者已經和發生衝突的文件的編輯同事商量好了。我們就要解決衝突了。

首先,上面說的三個文件,如果存在,我們就提交不了。

其次,需要選擇一個解決方法。

$svn resolve --accepting working reademe.txt

 

svn resolve 是解決衝突的命令。解決的方法由--accepting 選項決定。

base  恢復到衝突前的一個版本。

mine-full  恢復到以我的修改爲主的版本

their-full  恢復到庫中最新版本

working  手動解決

所以,上面的那句命令其實還有問題,因爲我們還沒有手工修改文件。

於是我們打開readme.txt,去掉哪些衝突標識

<<<<<<< .mine

hi

=======

hello

>>>>>>> .r9

修改爲 

No hi no hello

然後保存readme.txt

在使用 

$svn resolve --accepting working reademe.txt

注意,這一步以後,並沒有真正完成衝突解決。

$svn commit -m "conflict resole"

Sending        readme.txt

Transmitting file data .

Committed revision 10.

這次提交OK。衝突至此解決。

有時候,我們編寫到一半發現有人提交了更新或者是越寫越亂,我們想放棄這次編輯,恢復到上一個版本,當然,我們可以直接rm掉,然後update,我們也可以這樣:

$svn revert readme.txt

Reverted 'readme.txt'

問題解決以後,請使用svn status 查看一下狀態,是否正常了。

$svn status -vu readme.txt

                10       10 yinshaoxin   readme.txt

Status against revision:     10

沒有什麼MCD, ? 這些,說明狀態正常。

對於我們操作的這些,我們可以通過歷史svn log來查看狀態。

$svn log  

r9 | yinshaoxin | 2011-07-26 13:39:12 +0800 (Tue, 26 Jul 2011) | 1 line

shaoxin

------------------------------------------------------------------------

r8 | madic | 2011-07-26 11:12:47 +0800 (Tue, 26 Jul 2011) | 1 line

modify

------------------------------------------------------------------------

r7 | madic | 2011-07-26 09:35:51 +0800 (Tue, 26 Jul 2011) | 1 line

code

------------------------------------------------------------------------

r6 | madic | 2011-07-20 15:43:52 +0800 (Wed, 20 Jul 2011) | 1 line

pa

------------------------------------------------------------------------

r5 | madic | 2011-07-20 15:42:19 +0800 (Wed, 20 Jul 2011) | 1 line

p

------------------------------------------------------------------------

r4 | madic | 2011-07-20 10:40:03 +0800 (Wed, 20 Jul 2011) | 1 line

dir

------------------------------------------------------------------------

r3 | madic | 2011-07-19 14:01:49 +0800 (Tue, 19 Jul 2011) | 1 line

keywords

------------------------------------------------------------------------

r2 | madic | 2011-07-19 13:58:24 +0800 (Tue, 19 Jul 2011) | 1 line

new test

------------------------------------------------------------------------

r1 | madic | 2011-07-15 16:56:05 +0800 (Fri, 15 Jul 2011) | 1 line

ci chage

------------------------------------------------------------------------

天哪,所有的svn日誌都顯示出來了。我們可以使用r來確定一個範圍。

這就是時光機的歷史查看了。來吧,想看哪一個版本的。

$svn log -r 5:9

------------------------------------------------------------------------

r5 | madic | 2011-07-20 15:42:19 +0800 (Wed, 20 Jul 2011) | 1 line

p

------------------------------------------------------------------------

r6 | madic | 2011-07-20 15:43:52 +0800 (Wed, 20 Jul 2011) | 1 line

pa

------------------------------------------------------------------------

r7 | madic | 2011-07-26 09:35:51 +0800 (Tue, 26 Jul 2011) | 1 line

code

------------------------------------------------------------------------

r8 | madic | 2011-07-26 11:12:47 +0800 (Tue, 26 Jul 2011) | 1 line

modify

------------------------------------------------------------------------

r9 | yinshaoxin | 2011-07-26 13:39:12 +0800 (Tue, 26 Jul 2011) | 1 line

shaoxin

------------------------------------------------------------------------

注意  -r 5:9  和 -r 9:5 是不同的順序顯示。

當然也可以指定一個文件的版本日誌。

使用log注意,當你提交一個版本後,log並看不到這個日誌。

因爲 commit 和 update是獨立的。commit並不更新本地版本。我們只有使用 update以後,在使用log則可以看到。

還有,如果你使用svn log 不指定路徑的話,那麼默認的是當前的目錄。這樣,對於其他目錄的log,我們只有一條空日誌。

$-------------------------------------------

 

最後不要像我一樣,日誌都是亂七八糟,請重視日誌,因爲在以後查找問題梳理版本變化的時候,會對你有很大幫助。


好了,從現在開始,你已經基本掌握SVN的用法了。如果具體命令參數不會用,請使用 help 

如果你想了解的更多一點,那麼我們繼續看下一章。

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