perl程序自动找回cvs仓库中误删除的文件
昨天下午本想重新checkout仓库中一个模块(比如:moduleABC)里的某个子文件夹(比如:subDir),因本身就在这个子文件夹subDir中,用`cvs co -d . moduleABC/subDir`(.没作用啊,需要..\subDir才可以)结果就在本地嵌套了一个新的工作目录moduleABC,想删除这个新的文件夹moduleABC,忙晕了就直接
cvs rm -f moduleABC
cvs ci -m ""
结果把CVS仓库中moduleABC模块下subDir文件夹的代码全给删除了,
懊悔万分啊,不是害怕找不回来这些文件,方法很简单就是拿回dead前的一个版本,重新cvs add file;cvs ci file就行了。痛苦的是有几百个文件,这还不把我累晕倒。
没办法这种郁闷的体力活只能让可爱的Perl来干了,下面是Perl代码。我的环境是Windows平台,Linux平台没有测试过。
主要功能:找回cvs仓库中误删除的文件,需要指定$moduleName和$data(不能把不是误删的找回来)两个变量,我是假设环境变量CVSROOT已经设置过了,如果没有请你设置好再用,不然cvs老带上一长串命令用起来也很不爽。
另外,我假设删除之后没有手动恢复过,就是只恢复仓库模块中状态:dead为最后一个版本且匹配日期$data的那些文件。
//-----------------------------------------------------------
#! perl -w
use strict;
use warnings;
my $moduleName = "这里给出module名,请用你自己的替换"; # 模块名,假定已经设置环境变量CVSROOT
my $data = '2005/09/26'; # 误删除操作的日期,格式:/^\d{4}\/\d{2}\/\d{2}$/,如:'2005/09/26'
#------------------------------
my $tmpdir = 'c:/temp'; # 临时工作目录,最后请自己手动清理这个目录的空文件吧
my $logName = 'cvslog.txt'; # 临时日志文件
#------------------------------
mkdir $tmpdir;
my $log = "$tmpdir/$logName";
my %fileName_lastVersion;
sub parseLog
{
open F,$log || die("Can't open file $log:$!");
my $find_dead_version = 0;my $rfdv = \$find_dead_version; # No.?,find:-1
my $find_file_name = '';my $rffn = \$find_file_name;
while(<F>)
{
($find_file_name,$find_dead_version)=($1,0),next if(/^Working file: (.*)/); #,AUR5=ND<~C{(B
$find_dead_version=-1,next if(1==$find_dead_version && m!^date: $data.*author.*state: dead;!); #找到dead版本号
$find_dead_version>=0 && /^revision ([\d\.]*)/ && ++$find_dead_version; # revision count
$fileName_lastVersion{$$rffn}=$1,$$rffn='',next if('' ne $$rffn && -1==$$rfdv && /^revision ([\d\.]*)/); #找到last版本号
}
close F;
# while( my($k,$v) = each(%fileName_lastVersion) ){print "fileName:$k \t<==>\t lastVersion:$v\n";}
}
chdir("$tmpdir");system("cvs -Q co $moduleName");chdir("$moduleName");system("cvs -Q log -T > $log");
parseLog();
while( my($k,$v) = each(%fileName_lastVersion) )
{
chdir("$tmpdir/$moduleName");
my ($file_path,$file_name) = $k =~ /^(.*)\/(.*)/; # sub Directory
($file_path,$file_name)=('.',$k) if $k !~ /\//; # root Directory
print "$file_path\t$file_name\n";
chdir $file_path;
system("cvs up -r $v -p $file_name > $file_name");
system("cvs add $file_name");system("cvs ci -m '' $file_name");
}
(my $delpath = "$tmpdir/$moduleName") =~ tr/\//\\/;
system("del /s /q /f $delpath"); #没删除干净,全剩下空目录,自己动手吧
rmdir($delpath); #还是没删除干净,空目录自己清理吧 :)