分类:
2006-07-05 15:09:18
cvs log 命令的输出默认行为是所有branch上的所有revision, 下面
的命令可以让输出的各个revision按日期排序(实验结果, 并非cvs 文档记述),
cvs log -rBranch file_name
注意-r和Branch之间不能有任何东西. 但是如果没有任何选项来使用cvs log,
得到的各个revision之间并不是按日期来排序的, 下面的perl脚本会将cvs log的
输出按每个revision提交的日期排序, 可以正序(日期从旧到新), 也可以是反序(默认的
行为, 从新到旧显示), 因为反序是最为常见的用法, 所以参数-r表示日期从旧到新, 不
指定任何参数时默认从新到旧排序.
命令名: cvs_sortlog.pl
适用 : linux/unix, windows/cvsnt/cygwin. 使用ActivePerl的话命令行略作调整
参数 : -r 按revision提交日期从旧到新排序, 一般来说1.1 排在最前面
-# 其中#代表一个数字, 表示只输出前#个revision, 这样
cvs log filename | ./cvs_sortlog.pl -3
输出最近提交的三次revision号.
-a 不截断cvs log输出中date: 那一行的内容, 原样显示
使用的场合:
假设一个文件, 当前的revision号是 rev_5, 此时你提交了一个版本 rev_6, 稍后你
与同事沟通后发现保持到rev_5 才是正确的, 可惜cvs并不提供类似数据库中的回滚操作.
这时可以有几种做法, 其中一种就是将当前文件逆向更新:
cvs update -j rev_6 -j rev_5 file_name
注意这里两个-j参数的顺序, 必需是rev_6在前, 这样 file_name将会恢复到rev_5的状态
而它的版本号是 rev_6, 但是状态为Locally Modified.
然后再提交该文件:
cvs commit -m 'rollback to rev_5' file_name
这样, 就又得到了一个新的revision, 假设为rev_7, 它的内容跟rev_5是完全一样的.
上面的例子中用 rev_5这样的revision号来代替真实的修订号, 实际使用时却必需去找到
CVS系统生成的长长的版本号.
而如上所述, 默认的cvs log 输出是产生所有branch的输出, 各版本日期乱序排布.
经过这个脚本的过滤, 所有的版本都是按日期排序好的
额外地, 这个脚本默认把输出结果中的 date: 开头的那一行内容截短, 因为该行内容对
我来说往往太长容易把输出弄得混乱而其中的信息并没有什么用处.
下面的代码已我已经从网页上反向COPY回来测试过, 可放心使用
#!/usr/bin/perl
#
my $first_N = 10000000; #make it large enough
my $old_first = 0;
my $full_info = 0;
foreach $arg (@ARGV)
{
if( $arg =~ /-(\d+)/ )
{
$first_N = $1 + 0;
}
$old_first = 1 if( $arg =~ /^-r$/ );
$full_info = 1 if( $arg =~ /^-a$/ );
}
### output each revision separated by the default
my $cvs_rev_separator = "----------------------------\r?\n";
$\= "----------------------------\n";
### due to the limited cvs log input, read it all-in-one
$/="";
$all_rev_str =;
@revs = split(/$cvs_rev_separator/m, $all_rev_str);
#print $#revs;
my %all_revs;
my $header= "";
foreach $m (@revs)
{
do { $header= $m ; next } if grep(/^RCS file:/,split(/\n/,$m) ); #this record is header
my ($re,$date) = split(/\n/, $m);
#print "found date: $date\n";
## remove the fileds I don't care of
$m =~ s/\s*\b(?:state|lines|kopt|commitid):[^;]*;//g if (!$full_info);
## comment the next line if want to see the full info
$date =~ /^date: \d{4}\/\d{2}\/\d{2} \d{2}:\d{2}:\d{2};/ or die "bad date format: maybe
cvs change the log format $date\n";
$all_revs{$date} = $m;
}
my $n = 0;
my @all_dates = reverse sort keys %all_revs;
@all_dates = reverse @all_dates if $old_first;
print $header if length($header) > 0;
foreach $r (@all_dates)
{
exit if( $n >= $first_N);
print $all_revs{ $r };
$n++;
}