【1.業務需求】 為部門的 SVN伺服器添加一項commit 控制:即使用者在提交改變 時必須寫注釋,且不得低於10個字元。
【2.基本思路】 SVN本身並不提供這種強制寫log的功能,而是通過一系列的鉤子程式(我們稱為hook指令碼),在提交之前(pre-commit),提交過程中(start-commit),提交之後(post-commit),調用預定的鉤子程式來完成一些附加的功能。
本次我們要實現的是在提交到版本庫之前檢查使用者是否已經寫了注釋,當然要使用pre-commit這個鉤子程式。我們開啟 SVN的repository下的hook目錄,可以發現有好幾個檔案,其中一個是“pre-commit.tmpl”。這個檔案是一個模板檔案,它告訴了我們如何?提交前 控制。開啟該模板檔案,我們看到如下一段說明:
# The pre-commit hook is invoked before a Subversion txn is
# committed. Subversion runs this hook by invoking a program
# (script , executable , binary , etc.) named 'pre-commit' (for which
# this file is a template) , with the following ordered arguments:
#
# [1] REPOS-PATH (the path to this repository)
# [2] TXN-NAME (the name of the txn about to be committed)
#
# The default working directory for the invocation is undefined , so
# the program should set one explicitly if it cares.
#
# If the hook program exits with success , the txn is committed ; but
# if it exits with failure (non-zero) , the txn is aborted , no commit
# takes place , and STDERR is returned to the client. The hook
# program can use the 'svnlook' utility to help it examine the txn.
我們看到在一個提交事務執行之前,該hook指令碼會被調用。然後向該指令碼傳遞兩個參數:REPOS-PATH和TXN-NAME,一個是使用者要提交的URL,一個是本次事務的一個事務號。如果提交成功則返回0,否則返回其它非0結果。那麼我們的鉤子程式就是要在事務提交之前,攔截這些請求,然後通過svnlook命令來檢查是否已經寫了log。
【3.範例程式碼】 下面這段代碼是網上 直接拷貝的一段代碼:
@echo off
setlocal
set REPOS=%1
set TXN=%2
rem check that logmessage contains at least 10 characters
svnlook log "%REPOS%" -t "%TXN%" | findstr "." > nul
if %errorlevel% gtr 0 goto err
exit 0
:err
echo Empty log message not allowed. Commit aborted! 1>&2
exit 1
下面解析一下綠色高亮處代碼的作用:
①set REPOS=%1
set TXN=%2
還記得我們前面提到的但事務 提交時,會傳遞兩個參數嗎。這裡就是分別用來接收URL和事務號的
②svnlook log "%REPOS%" -t "%TXN%" | findstr ".........." > nul
這句是核心程式。首先svnlook log是用來查看某個版本庫某次提交的log的,那麼我們怎麼知道這兩個
參數呢。答案就是我們前面已經儲存的REPOS和TXN參數。
它的作用是查看%REPOS%這個URL第%TXN%次提交的log資訊,那麼| findstr ".........."呢。細心
的讀者會發現這裡有10個圓點號,即表示10個字元。
整句的作用就是先擷取當前提交的log內容,然後判斷是否有10個字元以上
③echo Empty log message not allowed. Commit aborted! 1>&2
這句話的作用是當提交檢查失敗時,輸出的提示資訊
【4. 運行測試及錯誤解決】 到這裡我們應該可以正常運行了吧。下面我們把上面這個程式儲存為pre-commit.bat,儲存到hook目錄下。啟動 SVN,隨意修改一個檔案後,不寫注釋提交。看看下面的結果: 居然提示我們找不到 svn repository目錄下的format檔案:
Svnlook:不能開啟檔案”C:\peng\Other\newRepo\fom…\” The system cannot find The path specified.
真鬱悶。這是什麼原因。仔細檢查檔案,沒有發現語法錯誤。從 SVN的官網上下了一份同樣內容的bat檔案,測試通過。那會不會是檔案的格式原因呢。我試著比較了這兩份檔案的字元數,發現居然不一樣。會不會是一些 控制字元的原因。
於是開啟舊的檔案,重新整理格式,發現每一行後面都多了一個 中文的分行符號。刪除這些分行符號再測試,測試通過。
教訓:從網頁上直接拷貝代碼有時會帶有特殊字元,諸如控制字元會中文空格等,這些字元有時會引起一些不必要的錯誤。