6 use FindBin qw($RealBin);
16 my $SVN_REPO="file:///home/svn/samba";
17 my $SVN_BRANCH="branches/SAMBA_4_0/";
18 my $SVN_PATH="$SVN_REPO/$SVN_BRANCH";
19 my $PATCH_PATH="$ENV{HOME}/svnmirror/samba4-sync.patches";
20 my $GIT_PATH="$ENV{HOME}/svnmirror/samba4-sync.git";
22 my $LAST_SVN_REV_PATH = "$PATCH_PATH/latest.rev";
24 sub get_last_svn_rev()
26 my $v = util::FileLoad($LAST_SVN_REV_PATH);
29 $v = $def if $v eq "";
33 print "get_last_svn_rev: $v\n";
37 sub set_last_svn_rev($)
41 util::FileSave($LAST_SVN_REV_PATH, $v);
42 print "set_last_svn_rev: $v\n";
48 my $infocmd = "LANG=C svn info --non-interactive $SVN_PATH";
49 my $info = `$infocmd` || confess "$infocmd: failed";
52 if ($v =~ /\nRevision: (\d+)/) {
55 $v = $def if $v eq $info;
59 print "get_cur_svn_rev: $v\n";
66 my $out = "$in\@samba.org";
74 my $delim = "------------------------------------------------------------------------";
75 my @tmp1 = split($delim, $in);
76 my @tmp2 = split("\n", $tmp1[0]);
80 last unless $l =~ /^[ \t]*$/;
84 my $out = join("\n", @tmp2);
99 return 1 if $in eq ".";
100 return 1 if $in =~ /\/$/;
104 sub construct_chunk($)
108 my $out = join("\n", @{$chunk->{content}->{lines}});
110 $out =~ s/^Index: ([^\n]+)\n[=]+/diff -u a\/$1 b\/$1/g;
111 $out =~ s/--- ([^\(]+)\(revision: 0\)/--- \/dev\/null/g;
112 $out =~ s/--- ([^\(]+)\([^\n]+/--- a\/$1/g;
113 $out =~ s/\+\+\+ ([^\(]+)\(revision: 0\)/+++ \/dev\/null/g;
114 $out =~ s/\+\+\+ ([^\(]+)\([^\n]+/+++ b\/$1/g;
119 sub strip_svn_properties($)
122 my @in = split("\n", $in);
126 foreach my $l (@in) {
127 if ($l =~ /^Index: ([\w\.\_\-\/]+)/) {
128 #print "content: $1\n";
131 $chunk->{type} = "content";
133 confess "$1 content exists" if defined($chunks->{$1}) and defined($chunks->{$1}->{content});
134 $chunks->{$1}->{content} = $chunk;
135 } elsif ($l =~ /^Property changes on: ([\w\.\_\-\/]+)/) {
136 #print "properties(".is_dir($1)."): $1\n";
139 $chunk->{type} = "property";
141 confess "$1 properties exists" if defined($chunks->{$1}) and defined($chunks->{$1}->{properties});
142 $chunks->{$1}->{properties} = $chunk unless is_dir($1);
145 push(@{$chunk->{lines}}, $l);
148 #print Data::Dumper::Dumper($chunks);
151 foreach $chunk (values %{$chunks}) {
152 #print Data::Dumper::Dumper($chunk);
153 my $v = construct_chunk($chunk);
157 my $out = join("\n", @out);
158 return undef if $out eq "";
168 confess("binary diff") if ($in =~ /Cannot display: file marked as a binary type/);
169 return undef unless ($in =~ /^Index: [\w\.\_\-\/]+/);
171 $out = strip_svn_properties($in);
176 sub get_new_svn_revs($$)
178 my ($lastrev, $currev) = @_;
179 my $nextrev = $lastrev + 1;
180 return undef if $nextrev >= $currev;
181 my $logcmd = "LANG=C svn log --non-interactive -r $nextrev:$currev $SVN_PATH";
182 my $log = `$logcmd` || confess "$logcmd: failed";
185 while($log =~ /\nr(\d+) \| (\w+) \| ([^\|]+) \|.*?line(s?)\n(.*)$/s) {
187 $revs->{$1}->{svnrev} = $1;
188 $revs->{$1}->{author} = fix_author($2);
189 $revs->{$1}->{log} = fix_log($5);
190 $revs->{$1}->{date} = fix_date($3);
200 my $diffcmd = "LANG=C svn diff --non-interactive -r $orev:$rev $SVN_PATH";
201 my $diff = `$diffcmd` || confess "$diffcmd: failed";
203 return fix_diff($diff);
206 sub generate_patch($$)
209 my @log = split("\n", $r->{log});
210 my $subject = shift @log;
211 my $body = join("\n", @log);
214 $p .= "From 123456780abcdef\n";
215 $p .= "From: $r->{author}\n";
216 $p .= "Date: $r->{date}\n";
217 $p .= "Subject: [PATCH] r$r->{svnrev}: $subject\n";
221 $p .= "\n---\nsvn-sync script\n\n";
229 my $applycmd = "cd $GIT_PATH && git am --binary $r->{patch_path}";
231 my $apply = `$applycmd` || confess "$applycmd: failed";
238 foreach my $rev (sort keys %{$revs}) {
239 my $r = $revs->{$rev};
240 $r->{patch_path} = "$PATCH_PATH/$r->{svnrev}.patch";
241 my $diff = get_svn_diff($r->{svnrev});
242 next unless defined($diff);
243 my $patch = generate_patch($r, $diff);
245 util::FileSave($r->{patch_path}, $patch);
247 set_last_svn_rev($r);
258 my $lastrev = get_last_svn_rev();
259 my $currev = get_cur_svn_rev();
261 my $revs = get_new_svn_revs($lastrev, $currev);
262 store_patches($revs);
263 #print Data::Dumper::Dumper($revs);