posts - 262,  comments - 221,  trackbacks - 0

          【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文件,測試通過!那會不會是文件的格式原因呢?我試著比較了這兩份文件的字符數,發現居然不一樣。會不會是一些控制字符的原因。

          于是打開舊的文件,重新整理格式,發現每一行后面都多了一個中文的換行符。刪除這些換行符再測試,測試通過!

          教訓:從網頁上直接拷貝代碼有時會帶有特殊字符,諸如控制字符會中文空格等,這些字符有時會引起一些不必要的錯誤。

           



          -------------------------------------------------------------
          生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
          posted on 2008-12-24 16:02 Paul Lin 閱讀(4735) 評論(1)  編輯  收藏 所屬分類: 項目管理


          FeedBack:
          # re: 【版本控制之路】SVN強制寫Log失敗的解決方案一例
          2008-12-27 16:22 | The Matrix
          good job  回復  更多評論
            
          <2008年12月>
          30123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          常用鏈接

          留言簿(21)

          隨筆分類

          隨筆檔案

          BlogJava熱點博客

          好友博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 文山县| 楚雄市| 潞城市| 新干县| 阿拉善右旗| 巧家县| 金山区| 珠海市| 巴东县| 武冈市| 绿春县| 鹤庆县| 保靖县| 陆丰市| 霍邱县| 兴化市| 海原县| 达尔| 南皮县| 西乌| 华容县| 开化县| 崇信县| 金溪县| 保德县| 弥渡县| 东宁县| 九龙坡区| 苗栗县| 长垣县| 乌什县| 建湖县| 澄江县| 泽州县| 武冈市| 四会市| 乐昌市| 洛阳市| 东平县| 长泰县| 额尔古纳市|