1. 程式人生 > >使用SVN鉤子強制提交日誌和限制提交檔案型別

使用SVN鉤子強制提交日誌和限制提交檔案型別

Subversion本身有很好的擴充套件性,使用者可以通過鉤子實現一些自定義的功能。所謂鉤子實際上是一種事件機制,當系統執行到某個特殊事件時,會觸發我們預定義的動作,這樣的特殊事件在Subversion裡有很多。那麼SVN的鉤子有哪些呢?下面簡單介紹下:

伺服器鉤子:

鎖定的2種

pre-lock

鉤子在每次有人嘗試鎖定檔案時執行。可以防止完全鎖定,或者用來建立控制哪些使用者可以鎖定哪些路徑的複雜策略。如果鉤子發現已存在鎖,也可以決定是否允許使用者“竊取”這個鎖。

post-lock

在路徑鎖定後執行。通常用來發送鎖定事件郵件通知。

解鎖的2種

pre-unlock

鉤子在某人企圖刪除一個檔案上的鉤子時發生。可以用來建立哪些使用者可以解鎖哪些檔案的策略。制定解鎖策略非常重要。如果使用者 A 鎖定了一個檔案,允許使用者B 開啟這個鎖?如果這個鎖已經一週了呢?這種事情可以通過鉤子決定並強制執行。

post-unlock

在一個或多個路徑已經被解鎖後執行。通常用來發送解鎖事件通知郵件。

提交的3種

start-commit

它在提交事務產生前已執行,通常用來判定一個使用者是否有權提交。版本庫傳給該程式兩個引數:到版本庫的路徑,和要進行提交的使用者名稱。如果程式返回一個非零值,會在事務產生前停止該提交操作。如果鉤子程式要在stderr中寫入資料,它將排隊送至客戶端。

pre-commit

在事務完成提交之前執行,通常這個鉤子是用來保護因為內容或位置(例如,你要求所有到一個特定分支的提交必須包括一個bug追蹤的ticket號,或者是要求日誌資訊不為空)而不允許的提交。版本庫傳遞兩個引數到程式:版本庫的路徑和正在提交的事務名稱,如果程式返回非零值,提交會失敗,事務也會刪除。如 果鉤子程式在stderr中寫入了資料,也會傳遞到客戶端。

post-commit

它在事務完成後執行,建立一個新的修訂版本。大多數人用這個鉤子來發送關於提交的描述性電子郵件,或者作為版本庫的備份。版本庫傳給程式兩個引數:到版本庫的路徑和被建立的新的修訂版本號。退出程式會被忽略。

屬性的2種

pre-revprop-change

因為Subversion的修訂版本屬性不是版本化的,對這類屬性的修改(例如提交日誌屬性svn:log)將會永久覆蓋以前的屬性值。因為資料在此可能 丟失,所以Subversion提供了這種鉤子(及與之對應的post-revprop-change),因此版本庫管理員可用一些外部方法記錄變化。作 為對丟失未版本化屬性資料的防範,Subversion客戶端不能遠端修改修訂版本屬性,除非為你的版本庫實現這個鉤子。

post-revprop-change

這個鉤子與pre-revprop-change對應。事實上,因為多疑的原因,只有存在pre-revprop-change時這個指令碼才會執行。當這 兩個鉤子都存在時,post-revprop-change在修訂版本屬性被改變之後執行,通常用來發送包含新屬性的email。版本庫傳遞四個引數給該 鉤子:到版本庫的路徑,屬性存在的修訂版本,經過校驗的產生變化的使用者名稱,和屬性自身的名字。

客戶端鉤子:

提交的

start commit hook

pre-commit hook

post-commit hook

更新的

start update hook

pre-update hook

post-update hook

今天研究了一下如何使用SVN鉤子強制提交日誌和限制提交檔案型別。這次我們用到的是服務端鉤子pre-commit。網上有篇文章使用jscript來實現這個功能:Windows下WSH/JS實現SVN伺服器鉤子指令碼阻止提交空日誌資訊和垃圾檔案。我測試過該文章,發現提交限制檔案時確實有效,但是提交正常的原始碼檔案時卻陷入一種類似死迴圈的等待中。我的測試環境是:客戶端 Win XP + sp3,伺服器端:WinServer2008 Enterprise。

為此只好自己參考網上的程式碼自己寫了一下,程式碼如下:

@echo 
rem SVN強制寫註釋的hooks指令碼(Windows)
rem 檔名是: pre-commit.bat,放到repository/hooks目錄下
setlocal
set SVN_BINDIR="C:\Program Files (x86)\SlikSvn\bin"
set REPOS=%1
set TXN=%2

rem 檢查是否提交日誌
%SVN_BINDIR%\svnlook log -t "%TXN%" "%REPOS%" | findstr "......" > nul
if %errorlevel% gtr 0 goto nolog

rem 過濾檔案型別
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "obj$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "pdb$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "idb$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "manifest$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "pch$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "res$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "exp$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "ilk$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "dep$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "user$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "suo$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "ncb$"
if %errorlevel% EQU 0 (goto SuffixError)
%SVN_BINDIR%\svnlook changed -t "%TXN%" "%REPOS%" | findstr "aps$"
if %errorlevel% EQU 0 (goto SuffixError)

exit 0
:SuffixError
echo 請不要提交受限制的檔案型別,如:obj、pdb、exp、ilk等等,謝謝! 1>&2
exit 1
:nolog
echo 日誌(Message)是跟蹤文件的重要資訊,必須輸入,不得輸入無意義字元,長度不得小於6個字元。 1>&2
exit 1

​ 簡單說明下:SVN_BINDIR路徑為你的SVN服務端程式所在的目錄,svnlookchanged -t "%TXN%" "%REPOS%" | findstr "obj$"為比較你提交的檔案是否為obj檔案(即字尾是否為obj)。

​ 部署方式是將上面的批處理程式碼儲存在pre-commit.bat(必須是這個名字),然後把它放到服務端的版本庫的hooks資料夾下。該指令碼經測試有效,測試環境為客戶端 Win XP + sp3,伺服器端:Win Server2008 Enterprise