windows下,分析svn日志提取变更

通过分析svn的日志,提取删除,变更,添加,并把这些变化放置到新的文件夹中。主要用途为版本更新


需要使用的工具 Subversion 命令行工具,下载地址:http://subversion.apache.org/


perl脚本 svn_log_extract.pl 代码如下:

use strict;
use warnings;
use File::Basename;
use File::Path;
use File::Copy;

my $usage = "usage: in_file result_file del_file match_pre src_pre dst_pre missing_file";
#default recipe dirs


if(scalar(@ARGV) < 7) {print STDERR $usage; exit 1;}

my $in_file = shift @ARGV;
my $result_file = shift @ARGV;
my $del_file = shift @ARGV;
my $match_pre = shift @ARGV;
my $src_pre = shift @ARGV;
my $dst_pre = shift @ARGV;
my $missing_file = shift @ARGV;

open(IN, "<", $in_file) or die $!;
my @file_content = ;
close IN;

#合并变更
my %result=();
{
	foreach my $item (@file_content)
	{
		if($item =~ /^\s+([A|D|M])\s(.+)/)
		{
			my $mod = $1;
			my $filename=$2;
			if($filename =~ /^$match_pre\//)
			{
				if(exists($result{$filename}))
				{
					my $src_mod = $result{$filename};
					if( $src_mod eq 'A' )
					{
						if ($mod eq 'D')
						{
							delete $result{$filename};
							del_dir($filename, \%result);
						}
					}
					elsif( $src_mod eq 'D' )
					{
						if ($mod eq 'A')
						{
							$result{$filename} = 'A';
						}
					}
					elsif( $src_mod eq 'M' )
					{
						if ($mod eq 'D')
						{
							delete $result{$filename};
							del_dir($filename, \%result);
						}
					}
				}
				else
				{
					$result{$filename}=$mod;
					if ($mod eq 'D')
					{
						del_dir($filename, \%result);
					}
				}
			}			
		}
	}
}


if ( ! -e  $dst_pre )
{
	# mkdir $dst_pre or die $!;
}

my @g_del_files=();
my @g_missing_files=();

#复制文件
{
	open(OUT, ">", $result_file) or die $!;
	while( my ($filename, $mod) = each %result )
	{
		if($mod eq 'D')
		{
			push @g_del_files, $filename;
		}
		else
		{
			my $src_name=$filename;
			$src_name =~ s/^$match_pre/$src_pre/;
			
			my $dst_name=$filename;
			$dst_name =~ s/^$match_pre/$dst_pre/;
			#目录替换
			if (-f $src_name)
			{
				my $dirname = dirname($dst_name);
				#建立目录
				mkpath($dirname);
				#拷贝文件
				# print "dirname=$dirname\n";
				# print $src_name, "=>",$dst_name,"\n";				
				copy($src_name,$dst_name)||warn "could not copy files :$!" ;
				# exit;
			}
			elsif (-d $src_name)
			{
				#建立目录
				mkpath($dst_name);
			}
			else
			{
				#不存在
				push @g_missing_files, "mod=$mod, filename=$filename, src_name=$src_name, dst_name=$dst_name";
			}
		}
		print OUT $mod, " ", $filename, "\n";
	}
	close OUT;
}

#输出到文件
if($#g_del_files > 0)
{
	open(OUT, ">", $del_file) or die $!;
	foreach my $item (@g_del_files)
	{
		print OUT $item, "\n";
	}
	close OUT;
}
if($#g_missing_files > 0)
{
	open(OUT, ">", $missing_file) or die $!;
	foreach my $item (@g_missing_files)
	{
		print OUT $item, "\n";
	}
	close OUT;
}
exit 0;


#dirname hash_filelist
sub del_dir
{
	my ($dirname, $hash_filelist) = @_;
	
	my @del_files = (); 
	#找到所有配料的路径
	while( my ($key, $value1) = each %$hash_filelist )
	{
		if( $key =~ /^$dirname\// )
		{
			push @del_files, $key;
		}
	}
		
	foreach my $item (@del_files)
	{
		delete $hash_filelist->{$item};
	} 
	
}

windows bat脚本 svn_log_extract.bat 代码如下

@echo off
setlocal

cd /d %~dp0

REM * 起始版本号 
set start_version=1862

REM * 结束版本号
set end_version=1927

REM * 日志前缀
set match_pre=/trunk/Server

REM * 签出的svn所在的目录
set src_pre=D:/wanghaibo/Server1/Server

REM 上面的例子中 假设把svn https://x.x.x.x/svn/Server/trunk/Server 签到了本地 D:/wanghaibo/Server1/Server
REM x.x.x.x/svn/Server 为仓库根目录
REM 则 match_pre 和 src_pre 配置上

REM * 输出目录
set dst_pre=D:/wanghaibo/Server1/inc

set tmp_dir=tmp

if not exist %tmp_dir% mkdir %tmp_dir%
del /Q %tmp_dir%\*

set in_file=%tmp_dir%/log.txt
set result_file=%tmp_dir%/result.txt
set del_file=%tmp_dir%/del.txt
set missing_file=%tmp_dir%/missing.txt


REM 生成日志
svn log -v -q -r %start_version%:%end_version% %src_pre%>%in_file%

REM 处理日志
perl svn_log_extract.pl %in_file% %result_file% %del_file% %match_pre% %src_pre% %dst_pre% %missing_file%

如果使用遇到问题可以发邮件给我
[email protected]
[email protected]

你可能感兴趣的:(svn,perl)