svn pre-commit hook 을 이용하여 허용되지 않은 파일 확장자는 repository 추가 막기

개발자가 실수로 불필요한 파일을 svn 저장소에 올리는 경우가 있다. (빌드로 생성되는 .exe, .obj, .class 등)

svn 의 특성상 추가된 파일은 삭제해도 저장소에는 남아있으므로 계속 공간을 차지하게 된다

 

svn 의 property 중 svn:ignore 를 사용해서 svn client 단에서 처리해도 되지만  프로젝트마다 설정하는게 귀찮을 수 있으므로 server 의 hook 기능을 이용하여 처리하고자 한다.

svn 1.8 에 추가된  svn:global-ignores 를 이용하면 server 단에서 처리할 수 있다.

 

 

commit 시 svnlook 으로 repository 의 변경 내역을 확인할 수 있는데 다음과 같은 형식을 갖게 된다.

svnlook changed 로 확인한 저장소 변경 내역

A my-proj/trunk/
A my-proj/trunk/a.cpp
D my-proj/dir/c.xml

 

첫번째 컬럼이 'A' 일 경우 파일/폴더 추가이고 'D' 는 삭제이다. (나머지 의미는 http://svnbook.red-bean.com/en/1.8/svn.ref.svn.c.status.html 참조)

폴더 추가의 경우 마지막이 '/' 으로 끝나므로 파일 추가일 경우 확장자를 검사해서 정해진 확장자만 추가되게 할 수 있다.

hooks/pre-commit
#!/usr/bin/php
<?php
$svnlook = 'svnlook';
$repos = $argv[1];
$txn = $argv[2];
$change = `$svnlook changed "$repos" -t "$txn"`;
## repos 에 추가 허용할 파일의 확장자
$white_list = array(".java", ".cpp", ".xml");
if ( ($ret = checkHasRestrictedFile($white_list, $change))) {
    fwrite(STDERR, "---------------------------------------------------------------------------\n");
    fwrite(STDERR, "You commit has been blocked because you are trying to commit a restricted file \n");
    fwrite(STDERR, "\"$ret\"\n");
    fwrite(STDERR, "---------------------------------------------------------------------------\n");
    exit(1);
}
function checkHasRestrictedFile($white_list, $changed)
{
    foreach(preg_split("/((\r?\n)|(\r\n?))/", $changed) as $line) {
        if ( substr($line,0, 2) == "A ") {
            $file_ext = substr(strrchr($line, "/"), 1);
            if (strlen($file_ext) > 0) {
                $ext = substr(strrchr($file_ext, "."), 0);
                if (!in_array($ext, $white_list)) {
                    return str_replace("A   ", "", $line);
                }
            }
        }
    }
    return null;
}
 
?>

Test

$:> svn add q.exe
A         q.exe
 
$:> svn commit -m "파일 추가"                     
Adding         my-proj/q.exe
Transmitting file data .svn: Commit failed (details follow):
svn: Commit blocked by pre-commit hook (exit code 1) with output:
---------------------------------------------------------------------------
You commit has been blocked because you are trying to commit a restricted file 
"my-proj/q.exe"
---------------------------------------------------------------------------

 

See Also