This link has been bookmarked by 9 people . It was first bookmarked on 10 Sep 2007, by York Jong.
-
20 Dec 09
-
會記住每一次檔案的變動
-
repository
-
你就可以把檔案回復到舊的版本, 或是瀏覽檔案的變動歷程. 許多人會把版本控制系統想像成某種 “時光機器”.
-
可用來管理任何 類型的檔案
-
泛用系統,
-
-
10 Sep 07
-
Subversion 是一個自由/開放源碼的版本控制系統, 也就是說 Subversion 管理著隨時間改變的檔案. 這些檔案放置在一個中央 檔案庫 (repository) 中. 這個檔案庫 很像一個尋常的檔案伺服器, 不過它會記住每一次檔案的變動. 這樣你就可以把檔案回復到舊的版本, 或是瀏覽檔案的變動歷程. 許多人會把版本控制系統想像成某種 “時光機器”
-
CVS 只能追蹤單獨檔案的歷史, 不過 Subversion 實作了一個 “虛擬” 的版本控管檔案系統, 能夠依時間追蹤整個目錄的更動. 目錄和檔案都 被納入版本控管. 最後, 用戶端有真正可用的 move (移動) 與 copy 指令
-
Subversion 使用二進制差異運算法, 來表示檔案的差異, 它對文字 (人類可理解的) 與二進制檔案 (人類無法理解) 兩類的檔案都一視同仁
-
Subversion 建立分支與標記的方法, 就只是複製該計畫, 使用的方法就像 hard-link 一樣. 所以這些動作只會花費很小, 而且是固定的時間
-

-
讓 Subversion 檔案庫如此不同的原因, 在於 它會記住所有的更動: 每個檔案的每一個更動, 甚至是每一個目錄所作的更動, 像是目錄與檔案的新增, 刪除, 以及重新編排
-
用戶端自檔案庫讀取資料時, 它通常只會看到最新版本的檔案系統樹. 但是用戶端也可以看到早先的檔案系統. 舉例來說, 用戶端可以詢問歷史性的問題, 像是 "上個星期三, 這個目錄裡有什麼東西?", 或 "誰是最後一個更動這個檔案的人, 而且作了哪些更動?"
-
許多版本控制系統以鎖定-修改-解鎖的方式 來解決這個問題
-

-
Subversion, CVS, 還有其它的版本控制系統使用一種 複製-修改-合併的模 型, 作為鎖定的取代方法
-

-

-
要是 Sally 的更動真的與 Harry 的更動重疊的話呢? 這該怎麼辦呢? 這種情況稱為 衝突 (conflict), 通常也不會是多大的問題. 當 Harry 要求用戶端程式將最新的檔案庫更動, 合併到他自己的工作複本時, 他自己的檔案 A 會被標示為衝突的狀態: 他可以看到兩邊互相衝突的更動, 然後手動在這兩者之間作選擇
-
複製-修改-合併模型聽起來有點混亂, 但是實務上跑起來可是相當地平順. 使用者可以同時各自工作, 不需等待他人. 當他們同時處理同一個檔案時, 大多數的情況下, 這些同時產生的更動都不會互相重疊; 衝突是相當少見的. 而且解決衝突所需要的時間, 也遠低於鎖定系統所損失的時間
-
每一次檔案庫接受一個送交的更動, 就會讓檔案樹進入一個新的狀態, 稱之為 修訂版本. 每一個修訂版本都會被賦與一個唯一的, 比前一個修訂版號大一的自然數. 一個新建立的檔案庫的修訂版號為零, 其中除了空的根目錄外, 什麼都沒有
-
不同於許多其它的版本控制系統, Subversion 的修訂版號是對整個樹有效, 而不僅只於個別的檔案. 每一個修訂版號都可選取整個樹, 它對應到某個更動送交之後的特定狀態的檔案庫. 另一個思考的方式, 就是版號 N 表示是第 N 次送交之後的檔案庫的檔案系統狀態
-
你可以藉由 svn status, svn diff, 以及 svn revert 這些命令, 來看看你所作的更動是什麼. 通常你會用前兩個命令, 來找你對工作複本所作的更動, 然後可能用第三個命令來復原這些更動
-
CVS 使用者: 別急著更新!
你可能曾用過 cvs update 來看看你對工作複本所作的更動. svn status 就可以得知所有你對工作複本所作過的更動的資訊— 不必存取檔案庫, 而且還不會不小心合併其它使用者發表的更動.
在 Subversion 中, update 就是作更動的動作— 它會將從你上次更新工作複本後所產生的所有更新, 通通更新到你的工作複本中. 你必須戒掉使用 update 以得知自己作過什麼修改的習慣
-
另一個檢視更動的方法, 是使用 svn diff 命令. 你可以得知 切確 修改的地方, 只要不帶引數執行 svn diff 即可
-
svn revert ITEM 的效果, 就跟自工作複本刪除 ITEM, 然後執行 svn update ITEM 是一樣的. 但是如果你要回復一個檔案, svn revert 有一個很重要的差異 — 它不需要與檔案庫溝通, 就能回復你的檔案
-
這三個命令 (svn status, svn diff, 以及 svn revert) 都可以在沒有網路可用的情況下使用. 在你沒有網路連線的情況下, 還是可以管理進行中的更動
-
檔案庫並不會知道, 也不管你的更動是否有意義; 它只會檢查是否有人在你沒注意時, 也修改了你所更動的檔案. 如果有人 也 修改到了, 那麼整個送交就會失敗, 並以一則訊息提示你, 有一個或多個檔案已經過時了:
$ svn commit --message "Add another rule"
Sending rules.txt
svn: Transaction is out of date
svn: Commit failed (details follow):
svn: out of date: `rules.txt' in txn `g'
$此時, 你需要執行 svn update, 處理產生的合併或衝突, 然後再試著送交一次
-

-
Subversion 有一些命令, 可以幫助你維持檔案與目錄的平行分支. 它讓你藉由複製資料來產生分支, 並且會記住這些複本是彼此相關的. 它也會幫你從一個分支中, 重製更動到另一個分支去. 最後, 它還能夠讓工作複本的不同部份反映出不同的分支, 這樣你就能在你每日的工作中, "混合搭配" 不同的發展路徑
-
建立一個分支相當地容易 — 利用 svn copy 命令, 在檔案庫中建立計劃的複本. Subversion 不僅能夠複製單一檔案, 整個目錄也沒有問題
-
現在介紹的是另一個建立分支較容易的方法, 我們該在一開始就告訴你: svn copy 可以處理兩個 URL.
$ svn copy http://svn.example.com/repos/trunk/calc \
http://svn.example.com/repos/branches/calc/my-calc-branch \
-m "Creating a private branch of /trunk/calc"
Committed revision 341. -

-
當你複製一個目錄時, 你不必擔心檔案庫會變得非常大 — Subversion 不會真的複製資料. 相反地, 它建立一個指向 現存 檔案樹的目錄項目. 如果你是一個 Unix 使用者, 這個概念就像 hard-link 一樣
-
-
你修改了 /branches/calc/my-calc-branch/button.c, 產生修訂版 342.
-
你修改了 /branches/calc/my-calc-branch/integer.c, 產生修訂版 343.
-
Sally 修改了 /trunk/calc/integer.c, 產生修訂版 344
這個工作複本沒有什麼特殊的地方; 它只是映射出另一個檔案庫的位置. 但是當你送交更動時, Sally 在更新時也不會看到它們. 她的工作複本是在 /trunk/calc.
讓我們假裝一個星期已經過去了, 而我們有以下的送交更動:
-
-

-
-
現在該是使用 svn merge 命令的時候. 這個命令結果是很像 svn diff 命令 (這在第 3 章就介紹過了). 這兩個命令都可以比較兩個檔案庫裡物件, 並表示它們之間的差異
-
svn merge 幾乎是完全一樣的. 但是它不會在終端機上顯示差異, 而是直接當成 本地修改 套用到你的工作複本上:
$ svn merge -r 343:344 http://svn.example.com/repos/trunk/calc
U integer.c
$ svn status
M integer.c -
如果你認為合併根本不是個好主意的話, 直接捨棄它, 以 svn revert 來回復本地更動
-
假裝你已經檢視過合併的更動, 你可以一如往常地使用 svn commit 來送交更動. 此時, 這個更動就被合併到你的 檔案庫分支. 在版本控制的術語中, 這個在不同的分支之間複製更動的動作, 稱為 移植 更動
-
svn merge 有一個優於 patch 程式的特殊功能. patch 所使用的檔案格式有其限制; 它只能處理檔案的內容而已. 它沒有辦法表達 檔案樹 的變動, 諸如目錄與檔案的新增, 刪除, 或是更名. 假如說 Sally 的更動新增了一個目錄, 那麼 svn diff 的輸出完全無法顯示. svn diff 只能輸出功能有限制的修補格式, 所以有些東西就是無法顯示出來. [8] 但是 svn merge 命令可以藉由直接套用檔案樹的更動到你的工作複本中, 來表示這樣的更動
-
掛勾 (hook) 是某些檔案庫事件所觸發的程式, 像是建立新的修訂版時, 修改未納入版本控制的性質時. 每一個掛勾都會得到足夠的資訊, 可以分辨出得到的是什麼事件, 針對哪個 (哪些) 目錄, 以及被誰觸發. 依掛勾輸出或傳回狀態的不同, 掛勾程式可以繼續, 停止, 或是暫停該動作
-
svn switch 命令可將現有的工作複本切換到不同的分支去. 雖然這個命令與分支運作沒什麼很直接的關係, 但是對使用者來說, 是個滿不錯的捷徑
-
建立一個簡單的標記
再一次地, svn copy 又來解救眾生了. 如果你想要建立一個完全符合 HEAD 修訂版的 /trunk/calc 的快照, 那就建立一個它的複本:
$ svn copy http://svn.example.com/repos/trunk/calc \
http://svn.example.com/repos/tags/calc/release-1.0 \
-m "Tagging the 1.0 release of the 'calc' project."
Committed revision 351. -
Subversion 的檔案庫是個中央倉儲, 用來存放任意數量專案的受版本控管資料
-
建立一個 Subversion 的檔案庫出乎意料地簡單. Subversion 所提供的 svnadmin 工具, 有個專門處理這件事的子命令. 要建立一個新的檔案庫, 只要執行:
$ svnadmin create path/to/repos
這會在目錄 path/to/repos 裡建立一個新的檔案庫. 這個新的檔案庫會以修訂版 0 開始其生命週期, 裡面除了最上層的根目錄 (/), 什麼都沒有. 剛開始, 修訂版 0 還有一個單一的修訂版性質 svn:date, 會設定在檔案庫初建立的時間
-
svnadmin 的路徑引數只是一個普通的檔案系統路徑, 而不是像 svn 用戶端程式用來表示檔案庫的 URL. svnadmin 與 svnlook 都被視為是伺服器端的工具 — 它們是在檔案庫所在的機器上, 對檔案庫作檢視或修改之用
-
svnlook 是 Subversion 提供的工具, 用來檢視檔案庫不同的修訂版與異動. 本程式完全不會試著去修改檔案庫 — 這是 “唯讀” 工具. svnlook 通常用在檔案庫掛勾程式中, 用來回報檔案庫即將送交的更動 (用在 pre-commit 掛勾時), 或剛送交的更動 (用在 post-commit 掛勾時). 檔案庫管理員也許會將這個工具用於診斷之用
-
Apache 提供了 htpasswd 工具程式, 來管理接受的使用者名稱與密碼
-
$ ### 第一次: 以 -c 建立檔案
$ htpasswd -c /etc/svn-auth-file harry
New password: *****
Re-type new password: *****
Adding password for user harry
$ htpasswd /etc/svn-auth-file sally
New password: *******
Re-type new password: *******
Adding password for user sally
$ -
-
使用你 現有 版本的 svnadmin, 將檔案庫傾印至傾印檔案.
-
升級至新版的 Subversion.
-
將舊的檔案庫移開, 在原處以 新版本 的 svnadmin, 建立新的空檔案庫
-
再利用 新版本 的 svnadmin, 將你的傾印檔載入至剛剛建立的檔案庫.
-
最後, 請記得將原來檔案庫的自訂部份複製到新的去, 包括 DB_CONFIG 與掛勾命令稿. 你應該要檢查一下新版本 Subversion 的發行備註, 看看從你上次更新後, 有沒有影響這些掛勾或設定選項的更動.
Subversion 檔案系統將其資料散佈在數個資料庫表格之中, 通常只有 Subversion 管理員了解 (也只有他們想了解). 但是有的時候, 我們需要將所有的資料, 或是部份的資料, 集合在單一可移植的平面檔. Subversion 提供這樣的機制, 由兩個 svnadmin 子命令實作出來: dump 以及 load.
傾印與載入 Subversion 檔案庫的最常見原因, 就是 Subversion 本身的改變. 隨著 Subversion 日漸成熟, 有時會因後端資料庫 schema 的改變, 導致 Subversion 與前一版的檔案庫不相容. 當你升級遇到這樣的相容性問題時, 我們建議以下列簡單的步驟來進行:
-
-
如果在傾印檔案庫時, 加上了 --incremental 選項, svnadmin 會將檔案庫的第一個傾印修訂版, 與檔案庫中前一個修訂版作比較, 就像其它被傾印的修訂版的處理方法一樣. 第一個修訂版的輸出, 就像傾印檔裡其它的修訂版輸出一樣 — 只會顯示該修訂版的更動部份而已. 這樣的好處, 是你可以建立幾個可連續載入的小傾印檔, 而不是一個很大的, 像這樣:
$ svnadmin dump myrepos --revision 0:1000 > dumpfile1
$ svnadmin dump myrepos --revision 1001:2000 --incremental > dumpfile2
$ svnadmin dump myrepos --revision 2001:3000 --incremental > dumpfile3這些傾印檔可以透過下列一連串的命令, 載入到新的檔案庫中:
$ svnadmin load newrepos < dumpfile1
$ svnadmin load newrepos < dumpfile2
$ svnadmin load newrepos < dumpfile3 -
通常最好的修訂版備份是包含多種方式的. 你可以妥善運用完整備份與漸進備分的組合, 再加上電子郵件的送交檔案
-
要讓你的檔案庫透過 HTTP 供他人存取, 基本上你需要四個元件, 可從兩個套件中取得. 你需要 Apache 的 httpd 2.0, 它也包含了 mod_dav 的 DAV 模組. Subversion, 以及包含的 mod_dav_svn 檔案系統供應模組
-
LoadModule dav_svn_module modules/mod_dav_svn.so
-
如果你計劃支援多個 Subversion 檔案庫, 而它們都有著共同的本地磁碟路徑, 你可以使用另一種指令 SVNParentPath, 指示它們共同的父路徑. 舉個例子, 如果你知道你會在路徑 /usr/local/svn 之下建立多個 Subversion 檔案庫, 並以類似 http://my.server.com/svn/repos1,http://my.server.com/svn/repos2 等等的 URL 供人存取, 你可以使用下列例子中的 httpd.conf 設定語法:
<Location /svn>
DAV svn
SVNParentPath /usr/local/svn
</Location>使用前述的語法, Apache 會將所有路徑以 /svn/ 開始的 URL 都交給 Subversion DAV 供應模組處理, 它會假設任何以 SVNParentPath 指令指定的目錄都是 Subversion 檔案庫. 不像 SVNPath, 這個相當便利的語法可以讓你在建立新的檔案庫時, 仍舊不必重跑 Apache.
-
Would you like to comment?
Join Diigo for a free account, or sign in if you are already a member.