

分享 Linux/Apache/PHP+MySQL/Smarty/JQuery/RubyOnRails 的點點滴滴!
1 背景假設
廈門央瞬公司是一家電子元器件設備供應商,其中有個ARM部門,專門負責ARM晶片的方案設計、銷售,並在北京、上海各設立了一個辦事處。對於工作日志,原先採用郵件方式發給經理,但是這種方式有個缺點,那就是不具備連續性,要看以前的日誌必須一封一封郵件去查看,很麻煩。於是就想到利用 Subversion, 讓員工在自己電腦上編輯日誌,然後利用svn傳送回來,既方便員工自己編寫日誌,又方便對日誌的歸檔處理,而且提交日誌的時候只需要執行一下 svn update 即可,比發送郵件還要簡單的多。
2 建立代碼庫
在伺服器 D:\svn 目錄下,建立 arm 代碼庫,命令如下:
D:\svn>svnadmin create arm
在客戶機 F:\temp 目錄下,建立好上述目錄結構
用命令 F:\temp>svnimportarmsvn://192.168.0.1/arm 導入結構
【注意點:關於導入時候的細微差別】
3 編輯代碼庫基礎設定檔
編輯代碼庫 arm\conf\svnserve.conf 文件,如下:
[general]
password-db = passwd.conf
anon-access = none
auth-access = write
authz-db = authz.conf
4 管理用戶帳號
新建代碼庫 arm\conf\passwd.conf 文件,如下:
[users]
morson = ShowMeTheMoney
michael = mysecretpassword
scofield = hellolittilekiller
lincon = asyouknows111
rory = 8809117
linda = IlikeWorldCup2006
5 建立目錄存取權限控制檔
新建代碼庫 arm\conf\authz.conf 檔,內容如下:
[groups]
g_vip = morson
g_manager = michael
g_beijing = scofield
g_shanghai = lincon
g_headquarters = rory, linda
g_docs = linda
[arm:/]
@g_manager = rw
* = r
[arm:/diary/headquarters]
@g_manager = rw
@g_headquarters = rw
@g_vip = r
* =
[arm:/diary/beijing]
@g_manager = rw
@g_beijing = rw
@g_vip = r
* =
[arm:/diary/shanghai]
@g_manager = rw
@g_shanghai = rw
@g_vip = r
* =
[arm:/ref]
@g_manager = rw
@g_docs = rw
* = r
[arm:/temp]
* = rw
6 測試
在伺服器上,打開一個 DOS Prompt 視窗,輸入如下指令:
svn co svn://127.0.0.1/arm --no-auth-cache --username rory --password 8809117
我們應該得到如下目錄結構:
arm
├─diary
│ └─headquarters
├─ref
└─temp
然後修改ref目錄下任意檔並提交,伺服器將會報錯“Access deni”
深入
本章將詳細介紹前一章所涉及的兩個設定檔, svnserve.conf 和 authz.conf,通過對配置逐行的描述,來闡明其中的一些細節含義。
這裡首先要注意一點,任何設定檔的有效配置行,都不允許存在前置空格,否則程式會無法識別。也就是說,如果你直接從本文的純文字格式中拷貝了相關的配置行過去,需要手動將前置的4個空格全部刪除。當然了,如果你覺得一下子要刪除好多行的同樣數目的前置空格是一件苦差使,那麼也許 UltraEdit 的“Column Mode”編輯模式,可以給你很大幫助呢。
1 svnserve.conf
arm\conf\svnserve.conf 文件,是 svnserve.exe 這個伺服器進程的設定檔,我們逐行解釋如下。
首先,我們告訴 svnserve.exe,用戶名與密碼放在 passwd.conf 文件下。當然,你可以改成任意的有效檔案名,比如默認的就是 passwd:
password-db = passwd.conf
接下來這兩行的意思,是說只允許經過驗證的用戶,方可存取碼庫。 那麼哪些是“經過驗證的”用戶呢?噢,當然,就是前面說那些在 passwd.conf 檔裡面持有用戶名密碼的傢伙。這兩行的等號後面,目前只允許 read write none 三種值,你如果想實現一些特殊的值,比如說“read-once”之類的,建議你自己動手改原始程式碼,反正它也是自由軟體:
anon-access = none
auth-access = write
接下來就是最關鍵的一句呢,它告訴 svnserve.exe,專案目錄存取權限的相關配置是放在 authz.conf 文件裡:
authz-db = authz.conf
當然,svn 1.3.2 引入本功能的時候,系統預設使用 authz 而不是 authz.conf 作為設定檔。不過由於鄙人是處女座的,有著強烈的完美主義情結,看著 svnserve.conf 有尾碼而 passwd 和 authz 沒有就是不爽,硬是要改了。
2 authz.conf 之用戶分組
arm\conf\authz.conf 檔的配置段,可以分為兩類,``[group]`` 是一類,裡面放置著所有使用者分組資訊。其餘以 [arm:/] 開頭的是另外一類,每一段就是對應著專案的一個目錄,其目錄相關許可權,就在此段內設置。
首先,我們將人員分組管理,以便以後由於人員變動而需要重新設置許可權時候,儘量少改動東西。我們一共設置了5個用戶分組,分組名稱統一採用 g_ 首碼,以方便識別。當然了,分組成員之間採用逗號隔開:
[groups]
# 任何想要查看所有文檔的非本部門人士
g_vip = morson
# 經理
g_manager = michael
# 北京辦人員
g_beijing = scofield
# 上海辦人員
g_shanghai = lincon
# 總部一般員工
g_headquarters = rory, linda
# 小秘,撰寫文檔
g_docs = linda
注意到沒有, linda 這個帳號同時存在“總部”和“文檔員”兩個分組裡面,這可不是我老眼昏花寫錯了,是因為 svnserve.exe 允許我這樣設置。它意味著,這個傢伙所擁有的許可權,將會比他的同事 rory 要多一些,這樣的確很方便。具體多了哪些呢?請往下看!
3 authz.conf 之專案根目錄
接著,我們對專案根目錄做了限制,該目錄只允許arm事業部的經理才能修改,其他人都只能眼巴巴的看著:
[arm:/]
@g_manager = rw
* = r
4 authz.conf 之項目子目錄
然後,我們要給總部人員開放日誌目錄的讀寫許可權:
[arm:/diary/headquarters]
@g_manager = rw
@g_headquarters = rw
@g_vip = r
* =
現在來看看
好了,我們現在掌握了“繼承”的威力,它讓我們節省了不少敲鍵盤的時間。可是現在又有一個問題了,
屬性具備覆蓋性質子目錄若設置了屬性,則完全覆蓋父目錄。
5 authz.conf 的其他注意點
把這個問題專門提出來,是因為在1.3.1及其以前的版本裡面,有個bug,即為了子目錄的寫許可權,專案首目錄必須具備讀許可權。因此現在使用了1.3.2版本,就方便了那些想在一個代碼庫存放多個相互獨立的專案的管理員,來分配許可權了。比如說央舜公司建立一個大的代碼庫用於存放所有員工日誌,叫做 diary,而arm事業部只是其中一個部門,則可以這樣做:
[diary:/]
@g_chief_manager = rw
[diary:/arm]
@g_arm_manager = rw
@g_arm = r
這樣,對於所有arm事業部的人員來說,就可以將 svn://192.168.0.1/diary/arm 這個URL當作根目錄來進行日常操作,而完全不管它其實只是一個子目錄,並且當有少數好奇心比較強的人想試著 checkout 一下 svn://192.168.0.1/diary 的時候,馬上就會得到一個警告“Access deni”,哇,太酷了。
如果說我對某個目錄不設置任何許可權,會怎樣?馬上動手做個試驗,將:
[diary:/]
@g_chief_manager = rw
改成:
[diary:/]
# @g_chief_manager = rw
這樣就相當於什麼都沒有設置。在我的 svn 1.3.2 版本上,此時是禁止任何訪問。也就是說,如果你想要讓某人訪問某目錄,你一定要顯式指明這一點。這個策略,看起來與防火牆的策略是一致的。
若設置了:
[arm:/diary]
* = r
則svnserve認為,任何人,都不允許改動diary目錄,包括刪除和改名,和新增。
也就是說,如果你在專案初期創建目錄時候,一不小心寫錯目錄名稱,比如因拼寫錯誤寫成 dairy,以後除非你改動 authz.conf 裡面的這行設置,否則無法利用 svn mv 命令將錯誤的目錄更正。
改進
1 對中文目錄的支援
上午上班的時候,Morson 來到 Michael 的桌子前面,說道:“你是否可以將我們的北京辦、上海辦目錄,改成用中文的,看著那些拼音我覺得很難受?” Michael 心想,還好這兩天剛瞭解了一些與 unicode 編碼相關的知識,於是微笑地回答:“當然可以,你明天下午就可以看到中文目錄名稱了。”
將設定檔轉換成 UTF-8 格式之後,Subversion 就能夠正確識別中文字元了。但是這裡需要注意一點,即必須保證 UTF-8 檔不包含 BOM 。BOM 是 Byte Order Mark 的縮寫,指 UNICODE 檔頭部用於指明高低位元組排列順序的幾個字元,通常是 FFFE ,而將之用 UTF-8 編碼之後,就是 EFBBBF 。由於 UTF-8 檔本身不存在位元組序問題,所以對 UTF-16 等編碼方式有重大意義的 BOM,對於 UTF-8 來說,只有一個作用——表明這個檔是 UTF-8 格式。由於 BOM 會給文本處理帶來很多難題,所以現在很多軟體都要求使用不帶 BOM 的 UTF-8 檔,特別是一些處理文本的軟體,如 PHP、 UNIX 指令檔等,svn 也是如此。
目前常用的一些文本編輯工具中,MS Windows 自帶的“記事本”裡面,“另存為”菜單保存出來的 UTF-8 格式檔,會自動帶上 BOM 。新版本 UltraEdit 提供了選項,允許使用者選擇是否需要 BOM,而老版本的不會添加 BOM。請各位查看一下自己常用的編輯器的說明文件,看看它是否支持這個功能。
利用 UltraEdit ,我們可以將 BOM 去掉。方法是,首先利用“UTF-8 TO ASCII”功能表將檔轉換成本地編碼,通常是GB2312碼,然後再使用“ASCII TO UTF-8(UNICODE Editing)”來轉換到 UTF-8 即可。
在上一篇帖子中介紹了Subversion版本控制軟體的安裝方法,另外還轉貼了一篇Subversion許可權控制的文章,出於工作的需要和學習態度的角度,還是希望自己到手來體驗Subversion許可權控制的魅力。
如果對Subversion安裝有疑問的話,請看作者另一篇帖子:http://www.blogjava.net/coldtear/archive/2006/08/04/61668.aspx,在這篇帖子裡詳細介紹了Subversion的安裝步驟。
在作者看了轉貼(《Subversion許可權詳解》)文章後,按照文章中的方法進行設置後,出現了一些問題,總是提示沒有許可權這樣的錯誤,錯誤提示為:“錯誤 Authorization failed”,對設定檔進行一些修改後,終於可以實現許可權控制了,這裡將作者碰到問題後的解決辦法寫出來,希望能給和我碰到同樣問題的朋友些幫助。
如果您按照http://www.blogjava.net/coldtear/archive/2006/09/05/67808.aspx這篇文章設置後,也提示沒有許可權的錯誤,那麼請您按照下面的方法操作。
修改conf\authz檔如下,主要是路徑的修改:
[groups]
g_vip = morson
g_manager = michael
g_beijing = scofield
g_shanghai = lincon
g_headquarters = rory, linda
g_docs = linda
#這裡多加了一個根目錄的許可權控制描述
[/]
@g_manager = rw
* =
#以下部分對路徑做了一些修改
[/arm]
@g_manager = rw
* = r
[/arm/diary/headquarters]
@g_manager = rw
@g_headquarters = rw
@g_vip = r
* =
[/arm/diary/beijing]
@g_manager = rw
@g_beijing = rw
@g_vip = r
* =
[/arm/diary/shanghai]
@g_manager = rw
@g_shanghai = rw
@g_vip = r
* =
[/arm/ref]
@g_manager = rw
@g_docs = rw
* = r
[arm:/temp]
* = rw
經過這樣的修改後,訪問時不會再報沒有許可權的錯誤,可以定制自己的許可權控制了。
Subversion對中文目錄的支援是非常好的,按照文章中的方法,可以很輕鬆的進行中文目錄的許可權控制,
當然,在保存authz檔時一定不要忘記選擇保存為“UTF-8 無BOM”。
蔡煥麟
huanlin.tsai at msa.hinet.net
Revision: 1.0 (Mar-18-2005)
一旦你使用了 Subversion 來管理版本,檔案庫就成為你開發時最重要的資產之一了,因此最好利用排程工具,定期將檔案庫備份,如果你的檔案庫都放在一個統一的目錄下,例如:d:/svn,就只要完整備份這個目錄就行了。
儘管你大部分時候都是使用視覺化工具(例如:TortoiseSVN)來執行版本控制的日常工作,熟悉命令列工具仍然非常有用,特別是當你要執行一些批次作業時。
有些團隊可能是用 nightly build 或 weekly build 的建置方式,然後對新建置的版本進行測試,這種方式可能是由專人負責建置,然後把新版的程式部署到測試機器上。
另一種可能的情況是,測試人員隨時都可以測試最新版的程式,也就是每當程式修改好,check in 到檔案庫之後,測試人員就要能測到最新版的程式。這種需求可以透過在測試機器上建立排程來達到,排程的工作是執行一個批次檔,而這個批次檔裡面就是些 Subversion 的 update 命令。例如:
REM 此批次檔用來更新測試機器的程式檔案
c:
cd\MyProject\BookWeb\BookWeb.war
svn update -N
cd Image
svn update
cd ..
cd Script
svn update
cd ..
cd Jsp
svn update
cd ..
cd WEB-INF\classes
svn update
cd ..\lib
svn update
cd ..
這種方式要注意一個問題,就是測試機器上的應用程式目錄裡面,每個目錄都會有一個隱藏的 .svn 目錄。如果要把測試機器上的檔案部署到用戶端,並且排除 .svn 目錄,就要使用 Subversion 的匯出(export)功能。
程式還有編譯錯誤及警告時,不要 check in 到檔案庫。一方面是基於測試的理由(程式當然是可以運作才放上去測試),另一方面,是因為這樣做可能會對別人造成困擾,因為別的開發人員可能有將整個專案 的程式碼取出,那麼每當他在本機上建置專案時,就會出現一堆編譯錯誤,包括他自己的程式和你的程式的錯誤。如果每個人都在程式還未能通過編譯時就 check in,那麼每次編譯專案產生的錯誤訊息將多到令人無法忍受。
每當我們要 check in 檔案時,Subversion 會要求我們輸入一段文字,用來簡單說明這次 check in 做了哪些改變。你可以把重要的備註事項寫進去,以後如果要回頭比對版本,可以幫助你更找到需要的版本。
以往沒有版本控制時,我們在修改程式時,常常會把一段程式碼註解掉,以便日後反悔時,可以恢復。但是這類註解掉的程式碼往往會一直留在那裡,直到程式改了好幾個版本,已經沒有利用價值以後,成為程式裡的一堆礙眼的垃圾。
有了版本控制以後,因為可以隨時回到任一個歷史版本,你可以放心的把不要的程式碼刪除,再配合實務 5,以後要恢復歷史版本就很容易了。
以往沒有使用版本控制系統時,我們有時候會自己做一點版本管理,例如修改 Foo.java 之前,先把它複製成一個新的檔案,並且加上序號,例如:Foo_1.java,然後再修改 Foo.java。現在有了版本控制系統,可以不用這樣了,免得多了一堆垃圾檔案。
我曾看過一種情況,就是有人還是習慣用附加編號的方式自己備份舊版的檔案,而且跟新版的檔案放在同一個目錄下,另一方面,他又習慣把程式的檔名用序號來命 名(懶得想個適切的檔名),結果備份的檔名和開發中的檔名都是用序號來命名,有一天某人要清理專案目錄中的垃圾時,就把所有帶序號的檔名都砍了,造成程式 無法編譯或執行。還好我們有時光機器可以回到過去,要不然就麻煩了。
如果你的作業系統不區分檔名的大小寫,例如:Windows,你最好第一次就把檔案名稱的大小寫確定下來。否則如果日後要改檔名,而且新的檔名和舊的檔名只有大小寫的不同,例如:myprg.java 和 MyPrg.java,你在送交和更新時可能會碰到一些麻煩。
在一個專案裡面,可能有些目錄裡面的某些檔案是你不希望加入檔案庫的,因此你在第一次匯入檔案庫之前,最好先把這些檔案搬移到別處,等到匯入檔案庫之後,在把它們搬回來,並且將這些檔案加入忽略清單。 以 Web 應用程式為例,參考下列步驟:
先大致建構出網站的雛形,檔案目錄結構大致底定之後,才將檔案匯入檔案庫。
建立檔案庫,並且準備匯入檔案庫。有一些檔案可能是你不希望進行版本控管的,因為當其他小組成員更新這些檔案之後,可能會造成他的開發環境出問題,例如: 無法編譯或執行程式等。不管是什麼原因,只要你有不想要放入檔案庫的檔案,就在匯入檔案庫之前,先把整個專案的檔案複製一份到一個暫存目錄下(c:\ temp),然後把 c:/temp 中所有不想控管版本的檔案刪除掉,然後再匯入檔案庫。匯入完成後把 c:/temp 底下的檔案全部刪除。
取出專案。先把整個專案的檔案*搬移*到 c:/temp 底下,接著從檔案庫取出(check out)專案,假設取出至 d:/myprj 目錄下。
把 c:/temp 底下的所有檔案複製到 d:/myprj,注意所有已經存在的檔案都不要覆蓋掉,亦即只複製新的檔案過去。這些新的檔案並未加入版本控制,你可以把它們加入忽略清單(ignore list)裡面,以後這些檔案就不會被存入檔案庫了。