首页 > 代码库 > 用PHP写的SVN post-commit

用PHP写的SVN post-commit

SVN提交代码时自动将发生改变的文件和目录更新到web目录:

1.根据更新svn日志,自动在/data/svn-update/mmoyu/目录update发生改变的分支目录

2.根据更新svn日志,从/data/svn-update/mmoyu/分支目录copy新增文件(或改变的文件)或者在目标目录删除文件(或文件夹)

PS   : 

        mmoyu是我的一个svn仓库, 

        51open是其中一个分支,

        日志生成在/data/www/logs/svn目录

#!/usr/local/php/bin/php
<?php
/**
 * svn hook post-commit written by php
 * @author : yearnfar
 * @website : http://51open.net
 */
 
define(‘SVNBIN_PATH‘, ‘/usr/local/svn/bin‘);
define(‘SVNLOG_PATH‘, ‘/data/www/logs/svn‘);
 
//$svnpath[lable] = array(svndir, updatedir, dstdir);
$svnpath["51open"] = array("51open", "/data/svn-update/mmoyu/51open", "/data/www/mmoyu/51open");
 
function main()
{
	global $argc, $argv, $svnpath;
	
	if ($argc < 3) exit("params error!");
	list(, $path, $no) = $argv;
 
	$logs = array();
	$info = array();
 
	if (popen_svnlook(‘info‘, $no, $path, $info)===-1) {
		exit("look info error!");
	} else {
		list($author, $time, $version, $message) = $info;
		$logs[] = "author: {$author}time: {$time}version: {$version}message: {$message}";
	}
 
	$logs[] = "change files:";
	$changefiles = array();
	if (popen_svnlook(‘changed‘, $no, $path, $changefiles)===-1) {
		exit("look changed error!");
	} else {
		$logs[] = implode(‘‘, $changefiles);
	}
 
	$logs[] = "change dirs:";
	$changedirs = array();
	if (popen_svnlook(‘dirs-changed‘, $no, $path, $changedirs)===-1) {
		exit("look dirs-changed error!");
	} else {
		$logs[] = implode(‘‘, $changedirs);
	}
 
	$sub = ‘‘;
	foreach ($changedirs as $dir) {
		//
		if ($sub==‘‘) {
			foreach ($svnpath as $k => $v) {
				if (strlen($dir)>strlen($v[0]) && substr($dir, 0, strlen($v[0]))==$v[0]) {
					$sub = $k;
					$offset = strlen($v[0]);
					break;
				}
			}
		}
		//
		if ($sub==‘‘) return ;
		//
		if (popen_svn(‘update‘, $no, $svnpath[$sub][1] . substr($dir, $offset))===-1) {
			exit("update error!");
		}
	}
 
	foreach($changefiles as $line) {
		$op = $line[0];
		$line = substr(trim(substr($line, 1)), $offset);
 
		$src  = $svnpath[$sub][1] . $line;
		$dst  = $svnpath[$sub][2] . $line;
 
		if ($op==‘D‘) {
			system_withlog("rm -rf {$dst}", $logs);
			continue;
		} elseif ($op==‘A‘) {
			if (!is_dir(dirname($dst))) {
				system_withlog("mkdir -p ".dirname($dst), $logs);
			}
		}
		//
		if (is_file($src)) {
			system_withlog("cp -f {$src} {$dst}", $logs);
		}
	}
 
	$logs[] = "\r\n\r\n";
	$logfile = SVNLOG_PATH."/{$sub}_{$no}.log";
 
	$fp = fopen($logfile, "wb");
	fwrite($fp, implode("\r\n", $logs));
	fclose($fp);
 
	echo "all files updated! logs: {logfile}";
	return ;
}
 
function popen_svnlook($cmd, $no, $path, &$ret = array())
{
	$ph = popen(SVNBIN_PATH."/svnlook {$cmd} -r {$no} {$path}", ‘r‘);
 
	while (($buffer = fgets($ph, 1024))!==false) {
		$ret[] = $buffer;
	}
	
	$errno = feof($ph) ? 0 : -1;
	pclose($ph);
 
	return $errno;
}
 
function popen_svn($cmd, $no, $path)
{
	$ph = popen(SVNBIN_PATH."/svn {$cmd} -r {$no} $path", ‘r‘);
	$ret = $ph ? 0: -1;
	pclose($ph);
	return $ret;
}
 
function system_withlog($cmd, &$logs=array())
{
	system($cmd);
	$logs[] = $cmd;
}
 
//run~
main();


用PHP写的SVN post-commit