Add git-shortlog perl script
Somebody finally came through - Jeff Garzik gets a gold
star for writing a shortlog script for git, so that I
can do nice release announcments again.
I added name translations from the current kernel history
(and git, for that matter). Hopefully it won't grow at
nearly the same rate the BK equivalent did, since 99% of
the time git records the full name already.
Usage: just do
        git-rev-list --pretty HEAD ^LAST_HEAD | git-shortlog
or, in fact, use any of the other tools (git-diff-tree,
git-whatchanged etc) that use the default "pretty" commit format.
			
			
				maint
			
			
		
							parent
							
								
									337cb3fb8d
								
							
						
					
					
						commit
						fa375c7f1b
					
				
							
								
								
									
										2
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										2
									
								
								Makefile
								
								
								
								
							|  | @ -23,7 +23,7 @@ INSTALL=install | ||||||
| SCRIPTS=git git-apply-patch-script git-merge-one-file-script git-prune-script \ | SCRIPTS=git git-apply-patch-script git-merge-one-file-script git-prune-script \ | ||||||
| 	git-pull-script git-tag-script git-resolve-script git-whatchanged \ | 	git-pull-script git-tag-script git-resolve-script git-whatchanged \ | ||||||
| 	git-deltafy-script git-fetch-script git-status-script git-commit-script \ | 	git-deltafy-script git-fetch-script git-status-script git-commit-script \ | ||||||
| 	git-log-script | 	git-log-script git-shortlog | ||||||
|  |  | ||||||
| PROG=   git-update-cache git-diff-files git-init-db git-write-tree \ | PROG=   git-update-cache git-diff-files git-init-db git-write-tree \ | ||||||
| 	git-read-tree git-commit-tree git-cat-file git-fsck-cache \ | 	git-read-tree git-commit-tree git-cat-file git-fsck-cache \ | ||||||
|  |  | ||||||
|  | @ -0,0 +1,167 @@ | ||||||
|  | #!/usr/bin/perl -w | ||||||
|  |  | ||||||
|  | use strict; | ||||||
|  |  | ||||||
|  | # | ||||||
|  | # Even with git, we don't always have name translations. | ||||||
|  | # So have an email->real name table to translate the | ||||||
|  | # (hopefully few) missing names | ||||||
|  | # | ||||||
|  | my %mailmap = ( | ||||||
|  | 	'aherrman@de.ibm.com' => 'Andreas Herrmann', | ||||||
|  | 	'akpm@osdl.org' => 'Andrew Morton', | ||||||
|  | 	'andrew.vasquez@qlogic.com' => 'Andrew Vasquez', | ||||||
|  | 	'aquynh@gmail.com' => 'Nguyen Anh Quynh', | ||||||
|  | 	'axboe@suse.de' => 'Jens Axboe', | ||||||
|  | 	'blaisorblade@yahoo.it' => 'Paolo \'Blaisorblade\' Giarrusso', | ||||||
|  | 	'bunk@stusta.de' => 'Adrian Bunk', | ||||||
|  | 	'domen@coderock.org' => 'Domen Puncer', | ||||||
|  | 	'dougg@torque.net' => 'Douglas Gilbert', | ||||||
|  | 	'dwmw2@shinybook.infradead.org' => 'David Woodhouse', | ||||||
|  | 	'ecashin@coraid.com' => 'Ed L Cashin', | ||||||
|  | 	'felix@derklecks.de' => 'Felix Moeller', | ||||||
|  | 	'gregkh@suse.de' => 'Greg Kroah-Hartman', | ||||||
|  | 	'hch@lst.de' => 'Christoph Hellwig', | ||||||
|  | 	'htejun@gmail.com' => 'Tejun Heo', | ||||||
|  | 	'jejb@mulgrave.(none)' => 'James Bottomley', | ||||||
|  | 	'jejb@titanic.il.steeleye.com' => 'James Bottomley', | ||||||
|  | 	'jgarzik@pretzel.yyz.us' => 'Jeff Garzik', | ||||||
|  | 	'johnpol@2ka.mipt.ru' => 'Evgeniy Polyakov', | ||||||
|  | 	'kay.sievers@vrfy.org' => 'Kay Sievers', | ||||||
|  | 	'minyard@acm.org' => 'Corey Minyard', | ||||||
|  | 	'R.Marek@sh.cvut.cz' => 'Rudolf Marek', | ||||||
|  | 	'simon@thekelleys.org.uk' => 'Simon Kelley', | ||||||
|  | 	'ssant@in.ibm.com' => 'Sachin P Sant', | ||||||
|  | 	'tony.luck@intel.com' => 'Tony Luck', | ||||||
|  | ); | ||||||
|  |  | ||||||
|  | my (%map); | ||||||
|  | my $pstate = 1; | ||||||
|  | my $n_records = 0; | ||||||
|  | my $n_output = 0; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | sub shortlog_entry($$) { | ||||||
|  | 	my ($name, $desc) = @_; | ||||||
|  | 	my $key = $name; | ||||||
|  |  | ||||||
|  | 	$desc =~ s#/pub/scm/linux/kernel/git/#/.../#g; | ||||||
|  | 	$desc =~ s#\[PATCH\] ##g; | ||||||
|  |  | ||||||
|  | 	# store description in array, in email->{desc list} map | ||||||
|  | 	if (exists $map{$key}) { | ||||||
|  | 		# grab ref | ||||||
|  | 		my $obj = $map{$key}; | ||||||
|  |  | ||||||
|  | 		# add desc to array | ||||||
|  | 		push(@$obj, $desc); | ||||||
|  | 	} else { | ||||||
|  | 		# create new array, containing 1 item | ||||||
|  | 		my @arr = ($desc); | ||||||
|  |  | ||||||
|  | 		# store ref to array | ||||||
|  | 		$map{$key} = \@arr; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | # sort comparison function | ||||||
|  | sub by_name($$) { | ||||||
|  | 	my ($a, $b) = @_; | ||||||
|  |  | ||||||
|  | 	uc($a) cmp uc($b); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sub shortlog_output { | ||||||
|  | 	my ($obj, $key, $desc); | ||||||
|  |  | ||||||
|  | 	foreach $key (sort by_name keys %map) { | ||||||
|  | 		# output author | ||||||
|  | 		printf "%s:\n", $key; | ||||||
|  |  | ||||||
|  | 		# output author's 1-line summaries | ||||||
|  | 		$obj = $map{$key}; | ||||||
|  | 		foreach $desc (@$obj) { | ||||||
|  | 			print "  $desc\n"; | ||||||
|  | 			$n_output++; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		# blank line separating author from next author | ||||||
|  | 		print "\n"; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sub changelog_input { | ||||||
|  | 	my ($author, $desc); | ||||||
|  |  | ||||||
|  | 	while (<>) { | ||||||
|  | 		# get author and email | ||||||
|  | 		if ($pstate == 1) { | ||||||
|  | 			my ($email); | ||||||
|  |  | ||||||
|  | 			next unless /^Author: (.*)<(.*)>.*$/; | ||||||
|  | 	 | ||||||
|  | 			$n_records++; | ||||||
|  | 	 | ||||||
|  | 			$author = $1; | ||||||
|  | 			$email = $2; | ||||||
|  | 			$desc = undef; | ||||||
|  |  | ||||||
|  | 			# trim trailing whitespace. | ||||||
|  | 			# why doesn't chomp work? | ||||||
|  | 			while ($author && ($author =~ /\s$/)) { | ||||||
|  | 				chop $author; | ||||||
|  | 			} | ||||||
|  | 	 | ||||||
|  | 			# cset author fixups | ||||||
|  | 			if (exists $mailmap{$email}) { | ||||||
|  | 				$author = $mailmap{$email}; | ||||||
|  | 			} elsif (exists $mailmap{$author}) { | ||||||
|  | 				$author = $mailmap{$author}; | ||||||
|  | 			} elsif ((!$author) || ($author eq "")) { | ||||||
|  | 				$author = $email; | ||||||
|  | 			} | ||||||
|  | 	 | ||||||
|  | 			$pstate++; | ||||||
|  | 		} | ||||||
|  | 	 | ||||||
|  | 		# skip to blank line | ||||||
|  | 		elsif ($pstate == 2) { | ||||||
|  | 			next unless /^\s*$/; | ||||||
|  | 			$pstate++; | ||||||
|  | 		} | ||||||
|  | 	 | ||||||
|  | 		# skip to non-blank line | ||||||
|  | 		elsif ($pstate == 3) { | ||||||
|  | 			next unless /^\s*(\S.*)$/; | ||||||
|  |  | ||||||
|  | 			# skip lines that are obviously not | ||||||
|  | 			# a 1-line cset description | ||||||
|  | 			next if /^\s*From: /; | ||||||
|  |  | ||||||
|  | 			chomp; | ||||||
|  | 			$desc = $1; | ||||||
|  | 	 | ||||||
|  | 			&shortlog_entry($author, $desc); | ||||||
|  | 	 | ||||||
|  | 			$pstate = 1; | ||||||
|  | 		} | ||||||
|  | 	 | ||||||
|  | 		else { | ||||||
|  | 			die "invalid parse state $pstate"; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | sub finalize { | ||||||
|  | 	#print "\n$n_records records parsed.\n"; | ||||||
|  |  | ||||||
|  | 	if ($n_records != $n_output) { | ||||||
|  | 		die "parse error: input records != output records\n"; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | &changelog_input; | ||||||
|  | &shortlog_output; | ||||||
|  | &finalize; | ||||||
|  | exit(0); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Linus Torvalds
						Linus Torvalds