_ another blog@hatena/Wiki/BBS
という語をぐぐる様してみたらひっかからなかったのでひとまずの仮称に。
Subversionでソースを育てていたけど、そろそろレポジトリへの新コードの導入に慎重になりたい、でも(svkなどの)分散SCMに移行する暇はない、ということででっちあげてみた。構想半日、製作2時間。でも格段に作業は楽になった。ということでひとまずここで晒しておく。
svnpatchwork.1.tar.gz_apply.pl
指定されたリビジョンでの修正のmergeとコミットコメントを自動生成してのコミットをやるperlスクリプト。lsunapply.plはこいつの自動生成コメントに依存しているので注意。$baseは設置プロジェクトに合わせて適当に修正すべし。
#!//usr/bin/perl
use strict;
my $base = 'svn/path/to/stableBranch';
if(@ARGV == 0){
print "$0 revision [revisions...]\n";
exit;
}
my(@revisions);
my $break = 0;
foreach(@ARGV){
if(/^r?(\d+)/){
push(@revisions,$1);
}else{
$break = 1;
chomp();
warn "wrong argv: '$_'\n";
}
}
my $comment = "merge from head: ";
foreach(@revisions){
my $cur = $_;
my $prev = $_ - 1;
system("svn merge -r$prev:$cur $base");
if($?){
"warn $?\n";
exit 1;
}
$comment .= "r$prev:$cur ";
}
system("svn commit -m '$comment'");
if($?){
"warn $?\n";
exit 1;
}
_lsunapply.pl
安定版側のapply.plの自動生成コメントと、trunk側のSubversionのログを頼りに、trunkには入っているが安定版側には未適用の修正の一覧を得るスクリプト。$base_rev、$trunk、$buildの3つの変数は設置プロジェクトに合わせて適当に修正すべし。
#!/usr/bin/perl
use strict;
my $base_rev = "1000";
my $trunk = 'svn/path/to/trunk';
my $build = 'svn/path/to/stableBranch';
my(@patches);
my(%patches);
open(IN,"svn log -r $base_rev:HEAD $trunk |");
while(<IN>){
if(/^r(\d+) \|/){
push(@patches, $1);
$patches{$1} = 1;
}
}
my(%commited);
open(IN,"svn log -r $base_rev:HEAD $build |");
while(<IN>){
while(/\d{4,}:(\d{4,})/g){
$commited{$1} = 1;
delete $patches{$1};
}
}
my(@uncommited) = sort {$a <=> $b} keys %patches;
print join("\n",@uncommited),"\n";
_diffcheck.sh:
指定したリビジョンについて、コミットログ+そのリビジョンで行われた修正のdiffの表示をしてくれる。こいつだけ独立で使っても普通に便利だと思う。trunkのチェックアウトディレクトリに置いて使う想定。
#!/bin/bash
if [ -z "$1" ]; then
echo usage: $0 revision
exit
fi
CUR=$1
PREV=$[$CUR - 1]
svn log -r$CUR
LANG=C svn diff -r $PREV:$CUR
適用したもののログ一覧が見たいとか言われたりした結果作ってみた。
今のところstableBranchの開始点だけが指定できる仕様。
というあたりが目先のわかってる改良点かなあ。
_applylog.pl
安定版側の指定されたリビジョン以降に適用された修正について、trunk側のログをまとめて出力する。安定版側のapply.plの自動生成コメントに依存する。
#!/usr/bin/perl
use strict;
my $trunk = 'svn/path/to/trunk';
my $build = 'svn/path/to/stableBranch';
if($ARGV[0] && $ARGV[0] !~ /^\d+$/){
warn "wrong argument: $ARGV[0]\n";
}
if(@ARGV == 0){
print "$0 revision\n";
exit;
}
my $base_rev = $ARGV[0];
my(%commited);
open(IN,"svn log -r $base_rev:HEAD $build |");
while(<IN>){
next if(/^r\d+ \| \w+ \| \d{4}-\d{2}-\d{2} \d\d:\d\d:\d\d/);
while(/\d+:(\d+)/g){
$commited{$1} = 1;
}
}
close(IN);
exit if scalar(keys %commited) == 0;
my $oldest = (sort {$a <=> $b} keys %commited)[0];
print $oldest,"\n";
open(IN,"svn log -r $oldest:HEAD $trunk |");
my $isTarget = 0;
while(<IN>){
if(/^r(\d+) \|/){
if($commited{$1}){
$isTarget = 1;
}else{
$isTarget = 0;
}
}
print if $isTarget;
}
close(IN);
なんとなく仕事キューが溜っていたという事情もあって徹夜仕事になってしまったのでついでに整備を進める。
といったあたりの作業をやった。tarボールをビルド用ツリーと目する場所で展開して、.svnpatchworkrcを書き換えれば使えるようになるんじゃないかと思う。svnpatchwork.2.tar.gz