14 use lib "$FindBin::Bin/../lib";
20 # ------------------------------------------------------------------------
26 my $bz = WWW::Bugzilla->new(
27 server => $cfg->{bugzilla}{server},
28 email => $cfg->{bugzilla}{user},
29 password => $cfg->{bugzilla}{pass},
30 bug_number => $set->{bug}
31 ) || croak "Cannot open bz - $!";
33 my $header = sprintf( "Git commit: %s/commitdiff/%s\n", $cfg->{gitweb}, $info->{rev} );
34 if ( scalar( @{ $info->{diff} } ) > 50 ) {
36 # big diff - we skip the diff
37 $bz->additional_comments(
38 join( "\n", $header, @{ $info->{info} }, '', @{ $info->{log} }, '----', @{ $info->{diffstat} } ) );
42 # otherwise we do the whole thing
43 $bz->additional_comments( join( "\n", $header, @{ $info->{all} } ) );
46 $bz->change_status("fixed") if ( $set->{action} =~ /fixes/ );
47 $bz->change_status("closed") if ( $set->{action} =~ /closes/ );
51 printf( "[%d] %s %s [%s]\n", $set->{bug}, $info->{rev}, $info->{log}[0], $set->{action} );
54 # ------------------------------------------------------------------------
55 sub find_bugzilla_references {
62 foreach my $line ( @{ $info->{log} } ) {
64 if ( $line =~ /(closes|fixes|references):?\s*(?:bug(?:zilla)?)?\s*\#?(\d+)/ ) {
68 elsif ( $line =~ /\b(?:bug(?:zilla)?)\s*\#?(\d+)/ ) {
69 $action = 'references';
78 push( @results, { bug => $bugid, action => $action } );
79 ##printf( "%s\n\taction = %s bugid = %s\n", $info->{rev}, $action, $bugid );
84 # ------------------------------------------------------------------------
90 my @lines = $git->run( 'show', '-M', '-C', '--patch-with-stat', '--pretty=fuller', $rev );
98 all => [@lines], # deliberate copy
101 while ( my $line = shift @lines ) {
102 last if ( $line =~ /^$/ );
103 push( @{ $info->{info} }, $line );
106 while ( my $line = shift @lines ) {
107 last if ( $line =~ /^---\s*$/ );
108 push( @{ $info->{log} }, $line );
111 while ( my $line = shift @lines ) {
112 last if ( $line =~ /^$/ );
113 push( @{ $info->{diffstat} }, $line );
117 $info->{diff} = \@lines;
122 # ------------------------------------------------------------------------
124 sub walk_git_commits {
128 my $lastrev = $git->run( 'rev-parse', $cfg->{lastref} );
129 my $headrev = $git->run( 'rev-parse', $cfg->{branch_head} );
131 return if ( $lastrev eq $headrev );
133 my @revs = $git->run( 'rev-list', '--topo-order', '--no-merges', ( $lastrev . '..' . $headrev ) );
135 foreach my $rev ( reverse(@revs) ) {
136 my $info = git_commit_info( $git, $rev );
139 #dd( $info->{info}, $info->{log}[0] );
140 my @sets = find_bugzilla_references( $info, $cfg );
141 foreach my $set (@sets) {
142 update_bugzilla( $cfg, $info, $set );
148 # ------------------------------------------------------------------------
155 'config=s' => \$config,
157 'verbose!' => \$verbose,
158 ) or die "Incorrect options";
159 die "No config file given\n" unless ( $config and -f $config );
160 my $cfg = ( values( %{ Config::Any->load_files( { files => [$config], use_ext => 1 } )->[0] } ) )[0];
162 die "No git_dir specified\n" unless ( $cfg->{git_dir} );
163 $cfg->{lasttag} ||= $cfg->{git_dir} . '/refs/tags/BugzillaDone';
164 $cfg->{branch_head} ||= 'HEAD';
166 $cfg->{lastref} = -f $cfg->{lasttag} ? read_file( $cfg->{lasttag} ) : 'HEAD';
167 chomp( $cfg->{lastref} );
169 my $git = Git::Repository->new( git_dir => $cfg->{git_dir} ) || die "No valid git repo\n";
171 my $newlast = walk_git_commits( $git, $cfg );
173 write_file( $cfg->{lasttag}, $newlast );