1. 引言
· 團隊開發?
· 修改檔案而他人也在改?你修改的内容丢失?
· 儲存了檔案可又後悔了?想得到幾天前的版本?
· 發現了bug,想知道bug何時引入的?
這些問題都遇到了?那就使用TortoiseSVN吧。TortoiseSVN是Subversion的用戶端。Subversion是針對CVS的不足而開發的版本控制系統。
2. 基本概念
檔案庫Repository
Subversion是版本管理的背景系統,其核心是儲存資料的檔案庫-repository。 檔案庫用分層的“檔案-目錄”檔案系統數來存儲資料。連接配接到檔案庫的客戶能讀寫資料。檔案庫記錄了你的每一次修改!用戶端可以從檔案庫中取到過去的版本。
圖2.1. 典型伺服器/客戶機模型
版本模型Versioning Models
基本問題:共享資料而不互相覆寫?
檔案共享的問題The Problem of File-Sharing
在合作開發中檔案共享的問題是顯而易見的。
圖 2.2. 要避免的問題
鎖定-修改-解鎖The Lock-Modify-Unlock Solution
Visual SourceSafe采用的就是這種模型。
Figure 2.3. 鎖定-修改-解鎖方案
問題:
· 鎖定可能引起管理問題: 如忘記解鎖别人無法使用。
· 鎖定造成不必要的串行作業。
· 鎖定可引起安全問題。
拷貝-修改-合并The Copy-Modify-Merge Solution
Subversion和CVS等采用拷貝-修改-合并模型。項目成員從檔案庫讀取個人的工作拷貝,所有項目成員并行地在工作拷貝上工作,然後合并在一起形成新的版本(version)。
圖 2.4. 拷貝-修改-合并方案
Figure 2.5. ...Copy-Modify-Merge Continued
如果修改不重疊,TortoiseSVN可自動合并。修改重疊則引起沖突(conflict)。沖突隻能靠手工修改!
這種模型好像很混亂,但實際上很好用。解決沖突的時間大大小于因鎖定而等待的時間。解決沖突的最好辦法是溝通。
實際操作Subversion
工作拷貝Working Copies
Subversion的工作拷貝就是包含檔案的本地目錄樹,與一般目錄的樹狀結構相同,可以進行任意的工作!工作結束後可将新的檔案“釋出”到檔案庫。
工作拷貝中包含了由Subversion建立和維護的一個特殊的子目錄.svn ,該目錄儲存了重要的資訊。不要删除這個目錄!
例如,假定你的檔案庫包含兩軟體項目:paint和calc。
圖 2.6. 檔案庫檔案系統
用取出(checkout)得到工作拷貝。
Repository URLs:檔案庫URL
Subversion的檔案庫借助不同方法得到:本地磁盤、網絡協定等:
Table 2.1. Repository Access URLs
Schema | Access Method |
file:/// | 本地磁盤. |
http:// | 透過Apache. |
例:
File:///c:/svn/prj/template ,
File:///c:/svn/prj/template/Dist
c:/svn/prj/template是檔案庫的目錄,Dist是檔案庫的子目錄名稱
http://build:88/prj/template
http://build:88/prj/template/Dist
http://build:88是Apache設定的URL,prj是通過Apache設定的位置,template是檔案庫名稱,Dist是目錄名
版本Revisions
svn commit 操作送交修改。檔案庫接受一次送交後,在檔案系統樹建立新的狀态,稱之為版本revision。每個版本是一個遞增的自然數。
圖 2.7. 檔案庫
全局版本号
版本号代表整個檔案庫而非單個檔案!
工作拷貝如何跟蹤檔案庫?
Subversion将下列兩種管理資訊記錄在.svn/:
· 工作版本 working revision
· 從檔案庫更新的時間。
通過這些資訊,在與檔案庫交換資訊後,Subversion可得出檔案的四種狀态:
l 未修改,新版本,送交無效
l 本地修改,新版本,可送交,更新無效
l 未修改,但在檔案庫中已修改,過期,送交無效,可更新
l 本地修改,在檔案庫中已修改,過期。先更新,修改沖突,再送交。
3. 伺服器設定
基于Apache的伺服器
這是設定Subversion伺服器的最好方法。優點:
l 利用WebDAV
l 用浏覽器浏覽檔案庫
l 認證
l 安全
本地檔案庫
用TortoiseSVN建立檔案庫
圖 3.1. 沒有版本控制的檔案夾TortoiseSVN菜單
1. 進入資料總管
2. 建立檔案庫的子目錄,如C:/SVNRepository。
3. 在建立的目錄中右鍵 TortoiseSVN->在此建立檔案庫Create Repository here....
可用FSFS和BDB兩種格式建立。
注意:不要編輯檔案庫中的檔案!
本地進入方式:file:///C:/SVNRepository/
檔案庫備份
最簡單的辦法是備份檔案庫檔案夾!
推薦辦法:
svnadmin hotcopy path/to/repository path/to/backup --clean-logs
4. 日常應用指南
操作TortoiseSVN
圖 4.1. TortoiseSVN右鍵菜單
所有TortoiseSVN指令均可以在資源浏覽器的右鍵菜單中執行。
認證
如果檔案庫設定了權限保護,則會彈出認證對話框。
圖 4.2. 認證對話框
如果使用Windows域認證,使用者名前需要包括域名,如MYDOMAIN/johnd.
資料彙入檔案庫Importing Data Into A Repository
檔案庫結構Repository Layout
根據不同需要來建立檔案庫的結構:
1. 建立新的空檔案夾。
2. 建立目錄結構 – 先不放檔案!
3. 右鍵菜單,點選彙入…(Import...)将結構加入到檔案庫中。
注意:檔案夾的名字不彙入檔案庫。
通過檔案庫浏覽器(Repo Browser)可直接浏覽檔案庫結構。
彙入Import
在将項目檔案彙入到檔案庫前,先進行下列操作:
1. 删除與項目無關的中間檔案如生成的臨時檔案*.obj等。 如果設定了忽略的檔案類型,或忽略的目錄,可不删除。
2. 在檔案夾中組織檔案。
在資源浏覽器中進入項目頂層檔案夾,右鍵得到快捷菜單,選擇彙入… (Import...) ,出現對話框:
圖 4.3. 彙入對話框
在對話框中輸入倉庫的URL。
彙入資訊(import message)作為記錄資訊。
注意
隻要點選确定OK TortoiseSVN将把整個目錄及目錄内的檔案加入到檔案庫中。頂層檔案夾的名字不會加入到檔案庫中,但其他子檔案夾的名字均加入以保持檔案庫的結構。該項目的檔案現在處在檔案庫版本控制中。請注意:目前的本地項目檔案夾不處在版本控制下!要得到版本控制,必須取出checkout檔案庫得到工作拷貝!
特殊檔案Special Files
有時你有一個包含使用者特定資料的檔案需要在版本控制下,這意味着每個開發人員需要修改它以适應他的本地設定,使用者每次送交均要儲存這檔案的變化,是以對這類檔案進行版本控制很困難。
對此建議使用template 檔案,建立一共檔案,它包含所有開發人員需要資訊,将它加入到版本控制下,每個開發人員均可取出這個檔案, 複制并重新命名,然後修改就沒有問題了。不需要加入版本控制的檔案可通過設定Subversion 特性(property) svn:ignored 來忽略。
取出工作拷貝Checking Out A Working Copy
從檔案庫執行取出(checkout)就能得到工作拷貝。
在資源浏覽器中標明将要存放工作目錄的拷貝,右鍵彈出快捷菜單,選擇C出…Checkout...,将出現對話框:(如果該目錄已在版本控制下,則沒有取出而是更新(Update)和送交(Commit))
圖 4.4. 取出對話框
如果檔案夾不存在,會自動建立。
注意
你隻能将檔案取出到一個空目錄裡。如果你想取出剛彙入的檔案,Subversion将報錯。你隻能将檔案取出到另一個目錄或先删除已經存在的源檔案再執行取出。
彙出Exporting
如果不想包含.svn ,可将檔案庫彙出到一個空目錄。這時所有檔案不處在版本控制下。方法:右鍵,選擇TortoiseSVN-〉 彙出…(Export...)。
狀态資訊Getting Status Information
通過圖示可知道檔案的狀态:修改/新增/删除/換名。
圖示
圖 4.5. 資源浏覽器顯示的圖示
新近取出的工作拷貝。Subversion狀态是正常normal.
檔案已修改,需要送交到檔案庫。Subversion狀态是已修改modified。
在更新檔案後自己的修改與他人的修改沖突。狀态是沖突conflict。
将加入到版本控制的檔案或檔案夾。狀态是新增added 。
檔案(夾)将從版本控制中删除,版本控制将忽略這些檔案(夾)。狀态是删除deleted。
檔案庫狀态 Status Of The Repository
圖 4.6. 檢查更新
想知道别人修改了哪些檔案?用檢查更新..(Check For Updates...) 指令。彈出的對話框将顯示出你的修改或檔案庫中别人的修改,這樣可在更新前檢查是否有沖突。
送交Commit.... 指令也可用來顯示本地的修改,如果不想實際送交到檔案庫,點選取消Cancel 即可。
将别人的改動更新到你的工作拷貝
圖 4.7. 已完成更新的進度對話框
有時你想将他人的改動合并到你本地的工作拷貝。從伺服器上取改動到本地的過程叫更新updating。 更新也許是單個檔案、或選擇的一組檔案、或整個目錄。在資源浏覽器中選擇待更新的檔案或目錄, 右鍵并選擇更新Update ,他人的修改将合并到你本地的檔案中,你所做的改動儲存在同一檔案中。這時檔案庫沒有受變化,即合并隻在本地進行。
如果你和他人改動的是相同部分但改動不一樣,就會在更新過程中産生沖突 conflicts。沖突在對話框中用紅色表示,輕按兩下後用外部編輯器解決沖突。
TortoiseSVN也允許你将工作拷貝更新到指定版本。用更新至版本Update to Revision... 指令,在彈出的對話框中輸入指定的版本号即可。
注意
如果你更新到指定版本,再送交是将出現out of date 錯誤!如果你想撤銷修改并從以前的版本開始工作,你必須使用從“顯示記錄”對話框中選擇複原自此版本以來的變更Revert changes from this revision 指令或使用快捷菜單中的合并Merge... 菜單指令。
更新至版本Update to Revision... 指令允許複原至低版本。比如你的工作目錄版本是100,你想複原至版本50-直接填寫在複原對話框中填寫複原至版本50。通常,不複原單個檔案,确實需要,從記錄對話框(Log)選擇儲存版本至Save revision to... 指令。
解決沖突Resolving Conflicts
有時你從檔案庫更新檔案會有沖突。沖突産生于兩人都修改檔案的某一部分。解決沖突隻能靠人而不是機器。當産生沖突時,你應該打開沖突的檔案,查找以<<<<<<<開始的行。沖突部分被标記:
<<<<<<< filename
your changes
=======
code merged from repository
>>>>>>> revision
Subversion為每個沖突檔案産生三個附加檔案:
filename.ext.mine
更新前的本地檔案。
filename.ext.rOLDREV
你作改動的基礎版本。
filename.ext.rNEWREV
更新時從檔案庫得到的最新版本。
使用外部合并工具或使用快捷菜單的編輯沖突Edit Conflict 指令來解決沖突。然後從快捷菜單中執行已解決Resolved 指令,将改動送交到檔案庫。請注意,解決指令并不解決沖突,而僅僅是删除filename.ext.mine and filename.ext.r* 檔案并允許你送交。
改動送到檔案庫Sending Your Changes To The Repository
這個過程叫送交committing 。 在送交前需要确認工作拷貝是最新的。用更新Updates 或先用檢查更新Check For Updates 檢查變更了的檔案。如果你的工作拷貝已更新且沒有沖突,可用快捷菜單中的送交Commit... 完成送交過程。
圖 4.8. 送交對話框
如果某檔案不想在版本控制下,取消複選框即可。
送交框中不需要控制的檔案
許多不需要版本控制檔案如obj檔案等也出現在送交對話框中,解決辦法:
· 在伺服器端編輯配置檔案config,将不需要控制的檔案 (或通配符)添加到排除檔案清單。其影響是全局的。
· 通過快捷菜單指令Add to ignore list将檔案添加到svn:ignore 清單。隻影響到本目錄。
圖 4.9.送交進度
加入新檔案或目錄Adding New Files And Directories
圖 4.11. 加入快捷菜單
開發中新增檔案或檔案夾,如需要加入到版本控制,選擇加入Add;如果不想要加入到版本控制,選擇加入忽略清單Add To Ignore List
Ignoring Files And Directories 忽略檔案和目錄
圖 4.12. 不需要版本控制快捷菜單
大多數項目會有一些檔案(夾)不需要版本控制,如編譯産生的*.obj, *.lst,等。每次送交,TortoiseSVN提示那些檔案不需要控制,挺煩的。
最好是在項目中加入忽略清單。
全局忽略清單The Global Ignore List
忽略檔案的另一個辦法是加入全局忽略清單global ignore list。 全局忽略清單是用戶端特性,他影響所有項目,但隻在該用戶端PC起作用。通常用 svn:ignore 會更好因為它對所有客戶起作用。
删除、換名和移動Deleting, Renaming And Moving
從快捷菜單的TortoiseSVN 子菜單進入删除、改名等操作
Figure 4.13. Explorer context menu for versioned files
如果你想在工作拷貝中移動檔案:
1. 選擇待移動的檔案和檔案夾;
2. 按住左鍵拖動right-drag 檔案(夾)到跟蹤拷貝内的新地方;
3. 松開左鍵
4. 在彈出菜單中選擇move files in Subversion to here
如果你在資料總管中象往常那樣删除了檔案而沒有在版本控制中删除,送交對話框将提示這些檔案并讓你在送交前在版本控制中删除它們。
撤銷修改Undo Changes
如果你想撤銷自上次更新後所作的改動,選擇檔案,左鍵right click,在快捷菜單的TortoiseSVN子菜單中選擇複原revert ,在對話框中選擇你想要複原的檔案,點選确定OK.
圖 4.14. 複原對話框
撤銷已送交的變更Undoing Changes which have been Committed
複原Revert 隻撤銷本地的改動,而不撤銷已送交檔案的改動。如果你想撤銷某一版本的全部變更,可從版本記錄對話框中處理。
Revision Log Dialog 版本記錄對話框
對每次送交的更改,你必須同時提供更改的記錄,以便日後能找出為什麼/如何改動。記錄對話框
記錄對話框顯示所有記錄資訊并顯示在3個格裡:
· 頂格顯示版本号,包括日期,送交者等。
· 中格顯示上格所選版本的完整記錄Log。
· 底格顯示該版本改動的檔案清單。
在頂格還提供快捷菜單!
彈出記錄對話框
圖4.15. 記錄對話框
彈出Log記錄對話框的方式:
· 從TortoiseSVN 子快捷菜單
· 從屬性頁
· 更新進度對話框。
分支/标記Branching / Tagging
版本控制的作用是能将變更隔離成獨立的方向,稱之為分支branch. 分支用于主釋出前嘗試新特性。
另一特性是标記特殊版本,以利于在任何時間重新建立環境。這個過程叫标記tagging.
Subversion并沒有特别的用于分支和标記的指令,而是用cheap copies代替。Cheap copies有點像連接配接links。
在由工作拷貝建立branch/tag前,你必須确認已更新檔案庫。
建立branch/tag非常簡單:
圖 4.18. 分支/标記對話框
從工作目錄父檔案夾點出快捷鍵,選擇分支/标記Branch/Tag... ,輸入檔案庫中存放分支/标記路徑的URL,在原來輸入trunk 的地方輸入tags/tagname ,這裡tagname 可能是ProjectName_v1.10.
C:/SVNRepository/trunk/ProjectName/...
C:/SVNRepository/trunk/AnotherProject/...
C:/SVNRepository/branches/ProjectName_SpecialDebugBuildBasedOn_v1.09/
C:/SVNRepository/tags/ProjectName_v1.10
點選OK ,Subversion在你選擇的檔案庫的目錄内建立了一個cheap copy。建立Branch / Tag不影響你的工作目錄。
取出或切換…To Checkout or to Switch...
…這确實是個問題!由于Checkout取出了分支中的所有資料, 轉向Switch... 隻是轉移你工作目錄中變化了的資料。
為了能在新的的工作拷貝上工作,你可以:
· 再次執行取出Checkout 。你可以取出任意次到你本地硬碟上的任何地方。
· 轉換到新建立的檔案庫拷貝上。隻需執行切換Switch...
在下面的對話框中輸入你的分支的URL,保留“Head Revision”點選 OK,你的工作目錄将切換到新的分支/标記branch / tag.
切換與更新,不會丢失你在本地所作的修改,而是将未送交的修改合并。
Figure 4.19. 切換對話框
分支與标記的不同點:
· 标記用于建立項目特殊階段的靜态快照 – 不再用于開發 – 而分支是用于開發的。這是我們建議使用/trunk /branches /tags 的理由。
· 如果你在工作拷貝上修改并送交,則在分支的修改展現在分支上而不是主幹上。。
将分支合并到主幹上
圖 4.20. 合并對話框
(略)
建立并應用更新檔Creating and Applying Patches
如果誰都可以修改,項目将沒完沒了,永遠不會穩定下來。怎麼辦呢?通過“更新檔patch”!将更新檔送交的具有寫權限開發團隊,他們先審查更新檔,再決定是否送交到檔案庫。
更新檔檔案僅顯示工作拷貝和基礎版本的差異。
Creating a Patch File 建立更新檔檔案
首先你需要測試你的修改是否正确,然後用建立更新檔Create Patch... 而不是使用送交Commit... ,這将建立包含改動的檔案。
Applying a Patch File 套用更新檔檔案
重新裝入工作拷貝Relocating a working copy
Figure 4.21. The Relocate Dialog
如果因為某種原因檔案庫修改位置,你需要使用重新定位指令。
檔案庫浏覽器The Repository Browser
直接在檔案庫上工作!
圖 4.22. 檔案庫浏覽器
進入檔案庫浏覽器後,使用快捷菜單!
誰動了我的奶酪?Who Changed Which Line?
Figure 4.28. 注解/譴責對話框
有時你不但要知道那些代碼改動了,還要知道誰改動的!使用追根溯源(譴責)Blame... 即可!将Blame翻譯成譴責真不好,其意思隻是追根溯源
圖 4.29. TortoiseBlame
使用内建在TortoiseSVN中的TortoiseBlame可非常友善地檢視修改的曆史
Final Step 最後
TortoiseSVN是開源項目,可通過http://svn.collab.net/repos/tortoisesvn/ 擷取最新的源代碼。這些源代碼是我們學習的極好的範本!
Enjoy it!