轉載自:http://blog.csdn.net/tengbaichuan/article/details/10632349
------------------ 參考文檔 --------------------
官方文檔: http://www.subversion.org.cn/svnbook/ 包括可下載的PDF 和一頁HTML。
配置文檔: 去ubuntu的wiki吧~~ 如果用 svn + ssh 的話,基本不用配置,按下面“快速工作”即可。
------------------ 快速工作: -------------------
1. 建立版本庫:
我的方式,是用svn+ssh來訪問版本庫,這意味著:
不用啟動svnserve守護進程,而是由每次ssh串連到版本庫時,自動啟動svnserve,工作完再退出svnserve進程。這些東西,都是本地的svn調用ssh讓它那樣做的。而啟動的svnserve進程的身份就是ssh使用者的身份,而ssh使用者來自於系統使用者,這就是這種方法的優點:就用系統使用者了。
正因為如此,每個使用者是否對版本庫能讀寫,就依賴於版本庫的使用權限設定,就是你用svnadmin create產生的檔案的使用權限設定。
我的策略是,為了讓某些使用者讀寫版本庫,我建立了一個svn使用者,和一個svn組,然後在/home/svn下建立版本庫。然後把所有需要訪問svn的使用者,加到svn組中,並設定版本庫的所有檔案,svn組的人都能夠讀寫。
在版本庫機器上,具體如下:
adduser svn # 建立svn使用者和svn組
gpasswd -a fengyi svn # 把fengyi使用者加到svn組
svnadmin create /home/svn/buptnic # 建立版本庫buptnic
chmod -R g+w /home/svn/buptnic # 讓所有的檔案為組可寫(因為預設一般是組可讀了)
以上兩步,也可以改為,先用umask 0002,再用svnadmin 一樣的效果。因為預設的umask一般是0022,這會去掉組的寫入權限。
注意:一旦svnadmin create之後,其他的事情,就應該用svn在工作拷貝機器上做了。———— 要點是,大部分svn的子命令,最終效果都是操作版本庫,但是分兩種途徑。如果子命令帶URL的,一般對版本庫直接操作,如果不帶URL的,一般是先對工作拷貝進行操作,然後用commit使版本庫生效。當然,好多命令,即可以帶URL,也可以不帶,一般都是先update,再更改工作拷貝,再commit。
在工作拷貝機器上,具體如下:
svn mkdir svn+ssh://svn@210.25.137.252/home/svn/buptnic/flow # 建立flow項目目錄
svn mkdir svn+ssh://svn@210.25.137.252/home/svn/buptnic/flow/trunk # 建立flow/trunk目錄
svn mkdir svn+ssh://svn@210.25.137.252/home/svn/buptnic/flow/branches # 建立flow/branches目錄
svn mkdir svn+ssh://svn@210.25.137.252/home/svn/buptnic/flow/tags # 建立flow/tags目錄
svn import /home/echo/src svn+ssh://svn@210.25.137.252/home/svn/buptnic/flow/trunk # 將本地的src下的源檔案匯入到版本庫的trunk目錄下。注意,trunk是主分支,一般習慣是放任何東西,包括文檔,第三方庫。
然後,就OK了,你可以找個地方,用fengyi使用者做checkout了。
svn checkout svn+ssh://fengyi@210.25.137.252/home/svn/buptnic/flow
注意的是:版本庫中,雖然你通過mkdir建立了那些目錄,上傳了那些檔案,但是,你是在/home/svn/buptnic/flow中直接看不到的,它們都放在flow 下的db目錄中,是虛擬檔案系統裡。
2. 使用者基本操作原則:
(1) 不管是 版本庫 還是 工作拷貝,他們的維護檔案,都在他們的檔案夾內,所以,如果要刪除他們,直接用檔案系統的rm即可徹底刪除。
(2) 用svn子命令,對版本庫的直接操作,必須用一種形式的URL,而不能是普通檔案路徑,包括在版本庫機器上。。。。。但是svnadmin等命令,就是直接用普通檔案路徑來操作版本庫,並要求在版本庫機器上執行。
(3) 在工作拷貝的哪個目錄執行 svn 子命令,該命令的最後一個參數,預設就是目前的目錄,這使得命令的效果從目前的目錄開始作用。
這從每個目錄裡有一個.svn看得出來,每個目錄都有維護檔案,都可以單獨工作。這也是工作拷貝的不同部分允許不同版本號碼的基礎。
(4) commit只有噹噹前目錄下所有檔案的版本號碼 等於 版本庫目前的版本號時,才能成功。
工作拷貝的不同部分允許不同版本號碼,所以,當你commit時,可能目前的目錄下,比如各個子目錄裡 的版本號碼並不同,如果有比版本庫低的版本號碼,commit就不能成功,提示資訊是 ... out of date ...,這時,你需要update一次,然後,再commit。當然,其他很多情形,也可能導致這種情況,最典型的就是(5)中檔案衝突的情況。
(5) 先在工作拷貝上操作,然後commit到版本庫。
除了修改檔案以外的任何操作,都用svn子命令完成,比如添加一個檔案,建立之後,用svn add添加到本地拷貝。當你覺得本次的工作拷貝工作結束時,可以將其commit到版本庫,使得版本庫更新到新的revision。
(6) 解決衝突
解決衝突最好的辦法,就是兩個人不要編輯同一個檔案。否則,見下面或資料,你就需要update一次,來合并兩人的檔案(因為別人先commit了,版本庫裡的版本號碼比自己的高,自己不會commit提交成功,需要先update)。如果需要手工解決衝突,見下面的解決辦法。
(7) 是的,如果兩個分支獨立發展太久,則必然改動較大,那merge是會有衝突的,你還是要手動解決。
merge和update衝突時,產生的衝突臨時檔案名稱不同,但是源檔案,都是被衝突標誌標註了的,你只需要改源檔案即可。裡面<<<到>>>部分,是衝突地區,即svn認為,在這個地區上,兩個檔案各自發展了自己的修改,所以第一個檔案的修改,放到<<<和===中,第二檔案的修改,放到===和>>>中,你自己選擇,保留哪個修改。如果某個修改為空白,即如===和>>>中沒有代碼,那說明“修改”就是“刪除”操作。
所以,當我們把branches的檔案merge到trunk時,得考慮清楚了,因為branches在修改bug,而trunk在增加新特性,為了把branches的bug修改通過merge引入trunk,是很可能導致衝突的。
(8) revert 和 merge
revert是在版本內恢複,即:當commit後,就是一個版本了,之後,如果更改了任何東西,但是還沒有commit的話,就可以恢複到上次commit後的狀態。revert不依靠版本庫,僅靠.svn目錄來維護資訊。
而merge,則是依賴版本庫,做的則是版本間的差異比較,從而作用於某個目錄。使得內容恢複到某個版本狀態。
(9) 忘了的命令,用svn help subcmd 來查閱。
(10) diff, status, log 怎麼用阿?
下面是trunk目錄下,svn status -v 的輸出:
28 28 fengyi .
28 26 fengyi sheep
28 26 fengyi sheep/sheep.c
28 20 svn main.c
28 28 fengyi cow
28 28 fengyi cow/main2.c
注意到:第一列是當前工作拷貝的版本號碼,是因為在trunk update後導致所有檔案的版本號碼變為最新。但是,後面的一列數字,表明自那個版本號碼以來,檔案沒有改過(不保證版本庫沒有更新)。你用svn log看那個檔案,也只能看到那個號版本,看不到當前工作拷貝的版本號碼(沒改,沒commit,怎麼可能有log。)
-------------------- 筆記 ---------------------
第一章 基本概念
svn就是能夠跟蹤資料變化的檔案伺服器
“拷貝-修改-合并”模型而不是“鎖定-修改-解鎖”(見儲存的圖)
每當版本庫由使用者commit了一個提交,檔案系統進入了一個新的狀態,叫做一次修訂(revision),每一個修訂版本被賦予一個獨一無二的自然數,commit顯然是原子操作。同時,可以看出,版本庫沒有回退的概念,只有工作拷貝有這個概念,版本庫只不過一直在往前走。
(許多其它版本控制系統使用每檔案一個修訂編號的策略,所以會感覺這些概念有點不一樣。)
SVN概念中,版本庫的修訂版本是統一的,就是說,任何時候,每個檔案的“修訂版本”都是一樣的。
但是工作拷貝中經常是“混合修訂版本”,因為你只提交一個檔案,導致版本庫中修訂版本加1,這時,你的工作拷貝中這個檔案的修訂版本也加1,但是工作拷貝中其他的檔案,只能維持原版本號碼,除非你update一次。
這是很有用的一個特性,它允許工作拷貝的任何一個部分在曆史中前進或後退。
svn有一個基本原則就是“推”動作不會導致“拉”,反之亦然。
svn commit & svn update 和 四種狀態 (是否修改+是否當前)
svn status --verbose 檢查“混合修訂版本”
svn log 顯示一個檔案或目錄的曆史修改資訊。
$ svn checkout http://svn.example.com:9834/repos
$ svn checkout file:///path/to/repos
$ svn checkout file://localhost/path/to/repos
C:\> svn checkout file:///X:/path/to/repos
$ svn checkout http://svn.example.com/repos/calc
$ svn commit button.c -m "Fixed a typo in button.c."
$ svn update
Subversion可以通過多種方式訪問版本庫!!
———— 一個重要意思是說:各種svn的子命令,都可以直接存取版本庫。如果你在版本庫機器上,那麼就用file:///,如果你在自己機器上,就用下面四種方式。
———— 但是,你怎麼只操作本地的工作拷貝呢,以為你想在本地改,改完後再commit,那就不要加這些東西了,直接是檔案名稱,或者不加就好。
模式 存取方法
file:/// 直接版本庫訪問(本地磁碟)
http:// 通過配置Subversion的Apache伺服器的WebDAV協議
https:// 與http://相似,但是包括SSL加密。
svn:// 通過svnserve服務自訂的協議
svn+ssh:// 與svn://相似,但通過SSH封裝。
但是注意:一般的做法,還是先update,merge,copy等命令把版本庫資料弄到工作拷貝,修改好工作拷貝後,再commit,這會導致版本庫的進入下一個revision。
如果直接在版本庫中操作的,比如copy,delete等,也會使得版本庫進入下一個reversion.
第二章 基本使用
svn help SUBCOMMAND
1. 建立版本庫
建立新的版本庫名 newrepos
$ svnadmin create /usr/local/svn/newrepos
將mytree下未版本化的檔案,匯入該版本庫,檔案放在some/project下,沒有mytree檔案夾了。
$ svn import mytree file:///usr/local/svn/newrepos/some/project -m "Initial import"
注意:import後的路徑,可以在版本庫上,也可以在自己機器上。一般,可以在自己機器上的代碼,直接這樣匯入伺服器上的版本庫。
列出newrepos版本庫中某檔案夾下的檔案。
$ svn list file:///usr/local/svn/newrepos/some/project
推薦的版本庫布局: 這裡有paint和calc兩個項目
$ svn list file:///usr/local/svn/repos
/paint/trunk
/paint/branches
/paint/tags
/calc/trunk
/calc/branches
/calc/tags
/vender/vendorlib1/current #供方最新版本
/vender/vendorlib1/1.0 #上次最新版本的快照(svn copy)
注意:檔案夾用 svn mkdir 建立。看你在版本庫主機上還是工作拷貝主機上,選用上面某一個URL可以對版本庫進行操作。
2. 初始化檢出
在本地建立一個工作拷貝,這個拷貝可能僅僅是一個版本庫中的一個檔案夾。
$ svn checkout http://svn.collab.net/repos/svn/trunk
同上,只不過,在本地建立的是subv目錄,