SVN

来源:互联网 发布:军工加人工智能的股票 编辑:程序博客网 时间:2024/06/04 19:18

Subversion脚本手册

1.      SVN全备份或增量备份

(一)全备份,包含两个文件hotcopy.bat和最终执行文件fullbackup.bat

1) hotcopy.bat

@echo 正在备份版本库%1……

rem @%SVN_HOME%/bin/svnadmin hotcopy %1 %BACKUP_DIRECTORY%/%2

@%SVN_HOME%/svnadmin hotcopy %1 %BACKUP_DIRECTORY%/%2

@echo 版本库%1成功备份到了%2

 

2)fullbackup.bat

echo off

rem Subversion的安装目录

rem set SVN_HOME="F:/Program Files/Subversion"

set SVN_HOME="F:/Program Files/CollabNet Subversion Server"

rem 所有版本库的父目录

set SVN_ROOT=G:/SVN

rem 备份的目录

set BACKUP_SVN_ROOT=h:/svnrootbak

set BACKUP_DIRECTORY=%BACKUP_SVN_ROOT%/%date:~0,10%

 

if exist %BACKUP_DIRECTORY% goto checkBack

echo 建立备份目录%BACKUP_DIRECTORY%>>%SVN_ROOT%/fullbackup.log

mkdir %BACKUP_DIRECTORY%

rem 验证目录是否为版本库,如果是则取出名称备份

for /r %SVN_ROOT% %%I in (.) do @if exist "%%I/conf/svnserve.conf" hotcopy.bat "%%~fI" %%~nI

goto end

:checkBack

echo 备份目录%BACKUP_DIRECTORY%已经存在,请清空。

goto end

:end

 

(二)增量备份,包含三个文件,dump.bat、最终执行文件svndump.bat和配置库名称配置projectlist.conf

1dump.bat

@ECHO OFF

rem 调用格式:dump 项目库名

if "%1"=="" goto no_args

set PROJECT=%1

if not exist %RAR_STORE%/%PROJECT% mkdir %RAR_STORE%/%PROJECT%

cd %RAR_STORE%/%PROJECT%

SET LOWER=0

SET UPPER=0

 

@echo 项目库%PROJECT%2...>> %Log_PATH%/%PROJECT%_log.txt

%SVN_LOOK% youngest %SVN_REPOROOT%/%PROJECT%> %Log_PATH%/A.TMP

@echo 项目库%PROJECT%3...>> %Log_PATH%/%PROJECT%_log.txt

@FOR /f %%D IN (%Log_PATH%/A.TMP) DO set UPPER=%%D

if %UPPER%==0 GOTO :N_EXIT

if not exist %Log_PATH%/%PROJECT%_last_revision.txt GOTO :BAKUP

rem 取出上次备份后的版本号,并做+1处理(注意此算法未在98系统验证)

@FOR /f %%C IN (%Log_PATH%/%PROJECT%_last_revision.txt) DO @set LOWER=%%C

@set /A LOWER=%LOWER%+1

rem 不需要备份,则跳转结束

IF %LOWER% gtr %UPPER% GOTO :N_EXIT

 

:BAKUP

SET FILENAME=%PROJECT%_%LOWER%_%UPPER%

@ECHO 开始备份项目库:%PROJECT%,生成文件=%FILENAME%

%SVN_ADMIN% dump %SVN_REPOROOT%/%PROJECT% -r %LOWER%:head --incremental >%FILENAME%.dmp

rem %RAR_CMD% a -df %PROJECT%_%UPPER%.rar %

rem 准备写备份日志信息

IF %LOWER% gtr 0 GOTO :WRITENOTE

@ECHO ------2-----%date% >> %Log_PATH%/%PROJECT%_log.txt

@echo  -- 3-------添加备份文件 %PROJECT%_%UPPER%.rar,从[%LOWER%][%UPPER%] >> %Log_PATH%/%PROJECT%_log.txt

GOTO :COMPLETE

 

:WRITENOTE

@ECHO %date% >> %Log_PATH%/%PROJECT%_log.txt

@echo  -- 4------添加增量备份文件 %PROJECT%_%UPPER%.rar,从[%LOWER%][%UPPER%] >> %Log_PATH%/%PROJECT%_log.txt

 

:COMPLETE

rem 下面一行用于拷贝备份文件到映射的驱动器上

rem copy %PROJECT%.rar %RAR_STORE%/%PROJECT%/

move %FILENAME%.dmp %RAR_STORE%/%PROJECT%/

del %Log_PATH%/A.TMP

@echo %UPPER% > %Log_PATH%/%PROJECT%_last_revision.txt

 

:N_EXIT

@echo 项目库%PROJECT%处理结束...>> %Log_PATH%/%PROJECT%_log.txt

@CD..

@exit /B

:no_args

@ECHO ON

@echo "正确调用方法: dump 项目库名"

 

2svndump.bat

echo off

rem Subversion的安装目录及执行文件

set SVN_HOME="F:/Program Files/CollabNet Subversion Server"

set SVN_ADMIN=%SVN_HOME%/svnadmin.exe

set SVN_LOOK=%SVN_HOME%/svnlook.exe

rem 配置库仓库根目录

set SVN_REPOROOT=G:/SVN

rem 压缩命令

set RAR_CMD="E:/Progra~1/WinRAR/WinRAR"

rem 增量备份文件存放路径

set RAR_STORE="H:/svnincrementW"

rem 日志及最后一次备份修订号存放文件目录,以下是跟增量备份脚本目录同一目录

set Log_PATH=G:/backup/incrementW

 

@echo 项目库%PROJECT%处理1...>> %Log_PATH%/%PROJECT%_log.txt

rem 读取项目库列表文件,并忽略其中;开头的行

FOR /f "eol=;" %%C IN (projectlist.conf) DO  call G:/backup/incrementW/dump.bat %%C

 

3projectlist.conf

;**************************************************

;01. project1开发库

;    更新频率:

;**************************************************

PROJECT1

;**************************************************

;02. 此处可写注释信息

;**************************************************

PROJECT2

PROJECT3

PROJECT4

PROJECT5

   

 

2.      客户端自动更新最新版本

此法的前提是在配置库所在服务器上编译,如需异机编译须采用同步来实现。

A.在编译机创建相应目录

首先,在编译机上,要安装相应的Subversion程序(不是TSVN),在某目录下创建文件夹,如E:/Proj1

切换到命令行形式,在该文件夹下执行:svn checkout svn://10.XX.XX.XX/svn/proj1(就是需要检出的库目录)

B.在SVN服务器端编写脚本

    要准备一个账户,可以检出和更新相应的配置库目录。

    拷贝版本库proj1文件夹(库文件)中hooks下的post-commit.tmplpost-commit,并修改post-commit (拷贝后的post-commit依然放在hooks目录下)

修改结果如下:

I.编译机为windows环境的:

#!/bin/sh

SET SVN="D:/subversion/bin/svn"    D:/subversion为编译机上Subversion程序的所在位置)

SET DIR="E:/Proj1"                (为编译机上待自动更新的目录)

SVN update %DIR%

(call %SVN% update %DIR% --username 用户名 --password 密码 --non-interactive)

II.编译机为UNIX环境的:

#!/bin/sh

SVN=/usr/bin/svn             (编译机上Subversion程序的所在位置)

TODIR=/home/testsvn         (编译机上待自动更新的目录,TODIR可以随便起名)

$SVN update --username xxx --password xxx $TODIR

III.编译机为LINUX及其它环境的:

1).在首行#!/bin/sh后面,补全编译机环境下的脚本格式

2).仿照WINDOSUNIX的写法,编写相应脚本

 

注:如果同时存在多个编译环境,可在首行#!/bin/sh后面补全脚本格式,在下面分别列出相应的脚本代码。或者,分别建立post-commit.batpost-commit.sh等等。

 

3.         自动生成每日提交统计文件

 

想知道开发人员在什么时间提交了那些文件,做的提交操作是什么,删除,增加,更新等等。在POST-COMMIT里面加如下代码:(已经在Windows下面通过,Linux大同小异)

@echo off

set SCMTXTDIR=D:/SCM_Program/TortoiseSVN

set TEMPDIR=D:/temp

set REPOS=%1

set REV=%2

set RD=%RANDOM%

set SVNTOOL=D:/SCM_Program/Subversion/bin/svn.exe

set SVNLOOKTOOL=D:/SCM_Program/Subversion/bin/svnlook.exe

set SVNADMINTOOL=D:/SCM_Program/Subversion/bin/svnadmin.exe

 

 

 

svnlook info %REPOS% > %TEMPDIR%/INFO_%RD%.txt

svnlook changed %REPOS% > %TEMPDIR%/CHG_%RD%.txt

 

以下是获取提交的用户名

sed -e "1p" -n %TEMPDIR%/INFO_%RD%.txt > %TEMPDIR%/temp_1.txt&&for /f "tokens=*" %%i in (%TEMPDIR%/temp_1.txt) do  set user=%%i

以下是获取提交的时间

sed -e "2p" -n %TEMPDIR%/INFO_%RD%.txt > %TEMPDIR%/temp_2.txt&&for /f "tokens=*" %%j in (%TEMPDIR%/temp_2.txt) do  set dtime=%%j

以下是获取提交的Comment信息

sed -e "4p" -n %TEMPDIR%/INFO_%RD%.txt > %TEMPDIR%/temp_3.txt&&for /f "tokens=*" %%k in (%TEMPDIR%/temp_3.txt) do  set LOG_MSG=%%k

 

 

获取提交的文件列表

cat %TEMPDIR%/CHG_%RD%.txt|sed "s/^D/Deleted File/"|sed "s/^A/Added   File/"|sed "s/^U/Updated File/"|sed "s/^_U/Updated Property/" > %TEMPDIR%/CHG_%RD%_2.txt

 

 

把提交的信息按照 文件名@日志信息@时间@用户的格式 写到日期文件夹里面去

if not exist D:/temp/Sourcecode/%date:~0,10% mkdir  D:/temp/Sourcecode/%date:~0,10%

cat cat %TEMPDIR%/CHG_%RD%.txt|sed "s/U/Updated The File@/g"|sed "s/A/Added The File@/g"|sed "s/D/Deleted The File@/g"|sed "s/@   /@/g"|sed "s/branches/%user%@%dtime%@%LOG_MSG%@branches/g"|sed "s/trunk/%user%@%dtime%@%LOG_MSG%@trunk/g"|sed "s/tags/%user%@%dtime%@%LOG_MSG%@tags/g" >> D:/temp/Sourcecode/%date:~0,10%/Info.txt

 

 

del %TEMPDIR%/INFO_%RD%.txt %TEMPDIR%/CHG_%RD%.txt %TEMPDIR%/INFO_%RD%.txt %TEMPDIR%/temp_1.txt %TEMPDIR%/temp_2.txt %TEMPDIR%/temp_3.txt %TEMPDIR%/MSG_%RD%.txt %TEMPDIR%/CHG_%RD%_2.txt %TEMPDIR%/MSG_%RD%.txt

 

4.         任何人不能窃取锁

pre-commit里面设置

获得锁的拥有者

@echo off

setlocal

set REPOS=%1

set PATH=%2

set USER=%3

set PDIR=C:/WINDOWS/system32

set SDIR=D:/SCM_Program/Subversion/bin

 

%SDIR%/svnlook.exe lock %REPOS% %PATH% |%PDIR%/sed.exe -n "2p"|%PDIR%/cut.exe -d ":" -f 2|%PDIR%/sed.exe "s/^ //g" > d:/temp/Unlock_Temp.txt&&for /f "tokens=*" %%i in (d:/temp/Unlock_Temp.txt) do

set OwnerUser=%%i&&del d:/temp/Unlock_Temp.txt

 

if "%OwnerUser%"=="" exit 0 为空 说明没有锁定

if

%OwnerUser% == %USER% exit 0 说明是自己锁定的

if

%OwnerUser% NEQ %USER% GOTO err 其他人锁定 退出

 

:err

echo %PATH%已经被%OwnerUser%锁定,你无权窃锁,请通知管理员. 1>&2

exit /B 1

 

5.         几个脚本

1)pre-commit

[实现了提交日志信息的校验,最少不能短于10.

2)post-commit

实现增量备份功能,工程师提交完毕后邮件通知功能,整理提交信息功能,把每次提交的信息都整理到一个文件里面,为以后生成配置管理报告提供很大的方便.

3)pre-lock

实现了防止窃锁的功能,不允许任何人窃锁,包括管理员.

4)pre-unlock

实现了防止工程师砸锁的功能除了管理员外,其他人无法砸锁.

给管理员留砸锁的权限是防止某些同志锁定文件后休假去了,其它人无法做修改.

当然这是基于锁定-修改-解锁的模式

5)post-unlock

给砸锁的人发邮件,告诉他不能砸锁

如果想砸锁跟管理员联系

 

6.         过滤特定后缀名,指定文件大小及必须填写注解

#!/bin/sh

REPOS="$1"

TXN="$2"

RES="OK"

#此处更改大小限制,这里是10M

MAX_SIZE=10240000

#此处增加限制文件后缀名

FILTER='/.(zip|rar|o|obj|tar|gz)$'

 

# Make sure that the log message contains some text.

#SVNLOOK=/usr/bin/svnlook

SVNLOOK=/opt/CollabNet_Subversion/bin/svnlook

 

$SVNLOOK log -t "$TXN" "$REPOS" | egrep  "[^[:space:]]+" >/dev/null || unset RES

if [ "$RES" != "OK" ]

then

echo "You must input some comments for you commit" >&2

exit 1

fi

 

files=$($SVNLOOK changed -t $TXN $REPOS |awk '{print $2}')

 

for f in $files

do

#check file type

if echo $f|tr A-Z a-z|grep -Eq $FILTER

then

echo "File $f is not allow ($FILTER) file" >&2

exit 1

fi

 

#check file size

filesize=$($SVNLOOK cat -t $TXN $REPOS $f|wc -c)

if [ "$filesize" -gt "$MAX_SIZE" ]

then

echo "File $f is too large(must <=$MAX_SIZE)" >&2

exit 1

fi

done

 

# All checks passed, so allow the commit.

exit 0

 

7.         版本库迁移(合并)的实现

版本库迁移(合并):指的是将两个独立的、有各自版本信息的版本库合并为一个版本库,并保留被合并的两个库的版本信息。

环境:windows+SVN+apache

我的版本库路径:c:/svn_repository(安装时的默认路径)

操作步骤:

1、在c:/svn_repository下新建两个版本库:test1test2,在test1中进行两次提交,增加文件夹ab和文件c.txt,产生两条版本信息,这里记为test1(1,2);在test2中进行五次提交,增加文件夹aabbccdd和文件ee.txt,产生五条版本信息,记为test2(1,2,3,4,5)

现在要做的是把版本库test1根目录下的所有内容(abc.txt)迁移到版本库test2的目录aa下;

2、运行cmd打开命令解释程序,首先输入命令:

svnadmin dump c:/svn_repository/test1 > dumpfile   ,此命令是将版本库test1的所有内容转储为名叫dumpfile的文件,当然,这个文件名可以随便;

3、然后输入命令:

svnadmin load c:/svn_repository/test2 --parent-dir aa < dumpfile  ,此命令是将test1的转储文件dumpfile读入版本库test2aa目录下,参数“--parent-dir”是为了指定test2下的具体路径,方法就是在“--parent-dir”后键入具体路径,这里的测试选择了一级目录aa

4、执行3中的命令并成功后,更新版本库test2,你会发现aa下面多了abc.txt ,查看test2log,会发现原版本库test2的版本信息没有变化,还是test2(1,2,3,4,5),新增了版本信息78,对应的就是原test1的版本信息test1(1,2),但除了Revision号由原来的12变为78外,其它没有变化。

如果你想把迁入的版本库test1里的内容再细致的分到test2的不同目录下,干脆直接用命令 svnadmin load c:/svn_repository/test2 < dumpfile  test1的内容迁移到test2的根目录下,然后再用TortoiseSVN的版本库浏览器做细致调整,反正版本信息都已经合并在一起了,后面的操作都是在一个版本库下,无碍无碍。

当然,在转储一个版本库的时候也可以选择性的转储,具体参数可以查看SVN手册,这里不再一一细表。

 

8.         控制开发人员新建文件夹的pre-commit脚本

以下是pre-commit内容的一部分,在Linux下面的subversion服务器里面测试通过。

 

      SVNLOOK=/usr/bin/svnlook

      REPOS="$1"

      TXN="$2"

      SCMLIST="user1,user2" #这里列举scmsvn用户名list,如果是scm新建文件夹,则不作判断。

      C_USER=`$SVNLOOK info  -t $TXN $REPOS|sed -n "1p"` #获得当前提交的svn用户

      if [ -z  `echo $SCMLIST|grep $C_USER`  ] # 如果做提交的用户不是scm,则做判断,如果是scm,则掠过这一部。

      then

      echo `$SVNLOOK changed -t $TXN $REPOS `  &gt;  /home/svnadmin/commit_log #放到一个临时的文件里面,这个可以自己定义,没办法,测试过,如果直接赋给变量,会报错,所以放到临时文件里面。

      if [ ! -z `cat /home/svnadmin/commit_log|tr " " "/n"|grep "^A$" -A 1|grep "//$"|sed  '/^[[:space:]]*$/d'|tr "/n" "@"` ]

       #这一步逻辑稍微有点复杂,调试了很久。就是判断提交的内容里面是否有新增的文件夹。新增的文件夹和新增的文件直接的区别是,新增文件夹后面会有个"/"

        这个在linux下面是如此

      then

        echo "you dont have the pession to create the new folder!please contach the scm if you want to do !" &gt;&gt; /dev/stderr

         #如果有新建的文件夹,则报错。

      exit 1

      fi

      rm -rf /home/svnadmin/commit_log

      fi

9.         过滤版本库历史(拆分)

svndumpfilter可以对版本库转储流进行特定路径的过滤。这是一个独特而很有意义的用法,可以帮助你快速方便的修改转储的数据。使用时,只需提供一个你想要保留的(或者不想保留的)路径列表,然后把你的版本库转储文件送进这个过滤器。最后你就可以得到一个仅包含你想保留路径(明确的或含蓄的)的转储数据流。

现在我来演示如何使用这个命令。我们会在其它章节(参见 规划你的版本库结构一节)讨论关于如何选择设定版本库布局的问题,比如应该使用一个版本库管理多个项目还是使用一个版本库管理一个项目,或者如何在版本库中安排数据等等。不过,有些时候,即使在项目已经展开以后,你还是希望对版本库的布局做一些调整。最常见的情况是,把原来存放在同一个版本库中的几个项目分开,各自成家。

假设有一个包含三个项目的版本库: calccalendar,和 spreadsheet。它们在版本库中的布局如下:

/

   calc/

      trunk/

      branches/

      tags/

   calendar/

      trunk/

      branches/

      tags/

   spreadsheet/

      trunk/

      branches/

      tags/

现在要把这三个项目转移到三个独立的版本库中。首先,转储整个版本库:

$ svnadmin dump /path/to/repos > repos-dumpfile

* Dumped revision 0.

* Dumped revision 1.

* Dumped revision 2.

* Dumped revision 3.

$

然后,将转储文件三次送入过滤器,每次仅保留一个顶级目录,就可以得到三个转储文件:

$ svndumpfilter include calc < repos-dumpfile > calc-dumpfile

$ svndumpfilter include calendar < repos-dumpfile > cal-dumpfile

$ svndumpfilter include spreadsheet < repos-dumpfile > ss-dumpfile

$

现在你必须要作出一个决定了。这三个转储文件中,每个都可以用来创建一个可用的版本库,不过它们保留了原版本库的精确路径结构。也就是说,虽然项目calc现在独占了一个版本库,但版本库中还保留着名为calc的顶级目录。如果希望trunktagsbranches这三个目录直接位于版本库的根路径下,你可能需要编辑转储文件,调整Node-pathCopyfrom-path头参数,将路径calc/删除。同时,你还要删除转储数据中创建calc目录的部分。一般来说,就是如下的一些内容:

Node-path: calc

Node-action: add

Node-kind: dir

Content-length: 0

 

警告

如果你打算通过手工编辑转储文件来移除一个顶级目录,注意不要让你的编辑器将换行符转换为本地格式(比如将/r/n转换为/n)。否则文件的内容就与所需的格式不相符,这个转储文件也就失效了。

剩下的工作就是创建三个新的版本库,然后将三个转储文件分别导入:

$ svnadmin create calc; svnadmin load calc < calc-dumpfile

<<< Started new transaction based on original revision 1

     * adding path : Makefile ... done.

     * adding path : button.c ... done.

$ svnadmin create calendar; svnadmin load calendar < cal-dumpfile

<<< Started new transaction based on original revision 1

     * adding path : Makefile ... done.

     * adding path : cal.c ... done.

$ svnadmin create spreadsheet; svnadmin load spreadsheet < ss-dumpfile

<<< Started new transaction based on original revision 1

     * adding path : Makefile ... done.

     * adding path : ss.c ... done.

$

svndumpfilter的两个子命令都可以通过选项设定如何处理修订版本。如果某个指定的修订版本仅包含路径的更改,过滤器就会将它删除,因为当前为空的修订版本通常是无用的甚至是让人讨厌的。为了让用户有选择的处理这些修订版本,svndumpfilter提供了以下命令行选项:

--drop-empty-revs

不生成任何空修订版本,忽略它们。

--renumber-revs

如果空修订版本被剔除(通过使用--drop-empty-revs选项),依次修改其它修订版本的编号,确保编号序列是连续的。

--preserve-revprops

如果空修订版本被保留,保持这些空修订版本的属性(日志信息,作者,日期,自定义属性,等等)。如果不设定这个选项,空修订版本将仅保留初始时间戳,以及一个自动生成的日志信息,表明此修订版本由svndumpfilter处理过。

尽管svndumpfilter十分有用,能节省大量的时间,但它却是把不折不扣的双刃剑。首先,这个工具对路径语义极为敏感。仔细检查转储文件中的路径是不是以斜线开头。也许Node-pathCopyfrom-path这两个头参数对你有些帮助。

Node-path: spreadsheet/Makefile

如果这些路径以斜线开头,那么你传递给svndumpfilter includesvndumpfilter exclude的路径也必须以斜线开头(反之亦然)。如果因为某些原因转储文件中的路径没有统一使用或不使用斜线开头,[33]也许需要修正这些路径,统一使用斜线开头或不使用斜线开头。

此外,复制操作生成的路径也会带来麻烦。Subversion支持在版本库中进行复制操作,也就是复制一个存在的路径,生成一个新的路径。问题是,svndumpfilter保留的某个文件或目录可能是由某个svndumpfilter排除的文件或目录复制而来的。也就是说,为了确保转储数据的完整性,svndumpfilter需要切断这些复制自被排除路径的文件与源文件的关系,还要将这些文件的内容以新建的方式添加到转储数据中。但是由于Subversion版本库转储文件格式中仅包含了修订版本的更改信息,因此源文件的内容基本上无法获得。如果你不能确定版本库中是否存在类似的情况,最好重新考虑一下到底保留/排除哪些路径。

最后,svndumpfilter就是字面上的意思,如果你尝试将目录trunk/my-project中的内容迁移到其自己版本库,你可以使用svndumpfilter include命令保持trunk/my-project目录下的所有修改。但是结果转储文件对于将要被加载入的版本库没有任何假定,特别的,目录trunk/my-project可能从创建这个目录的修订版本开始,而它不会包含以自己创建trunk目录的指示(因为trunk没有匹配include过滤)。在尝试将转储流存放到版本库之前,你需要确定任何转储流将要存在的目录必须存在于目标版本库。

10.              限制某个目录的提交日志最少字符

pre-commit.bat中输入如下字段:

setlocal

set REPOS=%1

set TXN=%2

 

REM repot && transaction arguments

REM svnlook command

 

svnlook changed "%REPOS%" -t "%TXN%" > a.txt

 

FOR /F "eol=; tokens=2,3* delims=,/ " %%i in (a.txt) do (

   if "%%i"=="1-DOC" goto changelog

    :changelog

     rem check that logmessage contains at least 5 characters

     svnlook log "%REPOS%" -t "%TXN%" | findstr "....." > nul

     if %errorlevel% gtr 0 goto err1

     exit 0

     :err1

     echo 提交必须按照规则写日志,且不能少于5个字符!>&2

     exit 1

   )

 

或:

@echo off

setlocal

set REPOS=%1

set TXN=%2

rem 必须要设置svnlook命令路径

set svnlook="C:/Program Files/CollabNet/Subversion Server/svnlook.exe" 

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 日志信息不能为空或者日志长度不够10个字符~请填写! 1>&2

exit 1

11.              限制开发人员不能删除文件或文件夹

pre-commit内容的一部分,在Linux下面的subversion服务器里面测试通过

 

SVNLOOK=/usr/bin/svnlook

REPOS="$1"

TXN="$2"

SCMLIST="user1,user2" #这里列举scmsvn用户名list,如果是scm新建文件夹,则不作判断。

C_USER=`$SVNLOOK info  -t $TXN $REPOS|sed -n "1p"` #获得当前提交的svn用户

if [ -z  `echo $SCMLIST|grep $C_USER`  ] # 如果做提交的用户不是scm,则做判断,如果是scm,则掠过这一部。

then

echo `$SVNLOOK changed -t $TXN $REPOS `  >  /home/svnadmin/commit_log #放到一个临时的文件里面,这个可以自己定义,没办法,测试过,如果直接赋给变量,会报错,所以放到临时文件里面。

if [ ! -z `cat /home/svnadmin/commit_log|tr " " "/n"|grep "^D$" -A 1|sed  '/^[[:space:]]*$/d'|tr "/n" "@"` ]

#这一步逻辑稍微有点复杂,调试了很久。就是判断提交的内容里面是否有新增的文件夹。新增的文件夹和新增的文件直接的区别是,新增文件夹后面会有个"/",这个在linux下面是如此

then

echo "you dont have the pession to del file!please contach the scm if you want to do !" &gt;&gt; /dev/stderr

#如果有新建的文件夹,则报错。

exit 1

fi

rm -rf /home/svnadmin/commit_log

fi

 

12.              限制文件提交类型

限制文件提交类型,利用perl脚本实现。如果操作系统是Linuxsolories,需要将perl脚本稍作修改转换成Shell即可执行。

1)  软件列表

在编写perl脚本前,先确认是否安装了perl插件。

操作系统

软件

Windows系列操作系统

ActivePerl-5.10.1.1006-MSWin32-x86-291086.msi或者更新版本

Linux或其他sun平台

不需要安装

 

2)脚本

hooks目录下,新建两个文件filter.pl文件和test.txt文件,内容如下:

use strict;

 

my @filter = ('rar','zip','tar','gz');#需要过滤的后缀列表

my $filter = join('|',@filter);

$filter = "[".$filter."]";

 

my $Ignore_dir = 1; #是否忽略文件夹下包含后缀限制文件的标志,1为忽略,0为不忽略

 

my $repos = $ARGV[0] ;

my $txn = $ARGV[1];

 

my $retu = `svnlook changed $repos -t $txn`;

 

 

my @file ;

my @line = split(//n/,$retu);

foreach my $line (@line){

    if($retu =~ /^A/s+(/S+.*)$/){

        push @file,$1;

        print "$1/n";

    }

}

if(@file == 0){

    exit;

}

 

if(@file >1 && $Ignore_dir == 1){

    exit;

}

else{

    my $file = $file[0];

    if($file =~ //.(/S+)$/){

        print $1."/n";

        my $suffix =  $1;

        if( grep(/^$suffix$/i,@filter)){

            warn "格式为$filter的文件不允许提交到svn!!!/n";

            exit -1;

        }

    }

}

 

exit;

 

2)  更新pre-commit 文件,如下:

perl D:/svn_repository/wuxian-test1/hooks/filter.pl %1 %2 >D:/svn_repository/wuxian-test1/hooks/test.txt|| exit 1

 

exit 0

 

保存后,进行测试。

 

3)  限制文件提交类型,具体文件类型可以根据需要自行增减。