3 $commitrange = shift @ARGV;
5 print STDERR
"Enter commitrange: ";
7 $commitrange =~ s/\s*(.*?)\s+/$1/;
10 $syncdate = shift @ARGV;
12 print STDERR
"Enter syncdate YYYY-MM-DD: ";
14 $syncdate =~ s/\s*(.*?)\s+/$1/;
19 print STDERR
'Enter kind ("lisp" or "texi" or "card" or press RET): ';
21 $kind =~ s/\s*(.*?)\s+/$1/;
22 $kind =~ s/"(.*?)"/$1/;
25 if ($kind ne "lisp" and $kind ne "texi" and $kind ne "card"
27 die "Invalid Changelog kind";
30 # commit must touch these paths or files to be considered
31 $fpath = "lisp/ doc/";
33 # Run git log to get the commits the messages
34 open IN
,"git log --no-merges --format='%aN%n<%aE>%n%b%x0c' $commitrange -- $fpath|";
37 @commits = split(/\f/,$log);
41 foreach my $commit (@commits) {
42 $name = ( $commit=~ s/([^\n]+)\n//m ) ?
$1 : "N/A";
43 $address = ( $commit=~ s/([^\n]+)\n//m ) ?
$1 : "N/A";
44 $tiny = $commit =~ s/TINYCHANGE//mg ?
" (tiny change)" : "";
49 # remove whitespace at beginning of line
50 $entry =~ s/^[ \t]*//mg;
52 # add linebreaks before each starred line except the very first
53 $entry =~ s/\A[\n\t]*/@/mg;
54 $entry =~ s/^\*/\n\n*/mg;
57 # normalize starred lines
58 $entry =~ s/^(\*[^(]*\S)\(/\1 (/mg;
60 # remove blocks of more than one empty line
61 $entry =~s/\n{3,}/\n\n/mg;
63 # Fix the path when directories have been omitted
64 $entry =~ s/^\* ([-a-zA-Z]+\.el)/* lisp\/$1/mg
;
65 $entry =~ s/^\* (org[a-z]*\.texi?)/* doc\/$1/mg
;
67 # remove stuff which is not for this output
69 remove_parts
("contrib/","testing/","xemacs/","UTILITIES/","etc/");
70 remove_parts
(".*Makefile","README",".+\.mk");
72 if ($kind eq "lisp") { remove_parts
("doc/") }
73 if ($kind eq "texi") { remove_parts
("lisp/","doc/orgcard","doc/orgguide") }
74 if ($kind eq "card") { remove_parts
("lisp/","doc/org\\.","doc/orgguide") }
76 # remove/replace parts of the path
77 $entry =~ s
:^\
* lisp
/:* :mg
;
78 $entry =~ s
:^\
* doc
/orgcard:* refcards/orgcard
:mg
;
79 $entry =~ s
:^\
* doc
/:* misc/:mg
;
81 # remove empty space at beginning and end
85 # remove everything that is not a starred entry
86 my @entries = grep( /^\*/, split( /\n\n/, $entry ));
88 # If there is anything left in the entry, print it
89 if (scalar @entries) {
90 push @
{ $entries{"$syncdate $name $address$tiny"} }, @entries;
94 foreach my $key ( sort keys %entries ) {
95 next if (! exists $entries{"$key"} );
97 if ( exists $entries{"$key (tiny change)"} ) {
98 push @
{ $entries{"$key"} }, @
{ $entries{"$key (tiny change)"} };
99 delete $entries{"$key (tiny change)"};
101 my @entries = @
{ $entries{"$key"} };
102 foreach my $entry ( @entries ) {
103 # indent each line by exactly one TAB
112 $re = "^[ \t]*\\*\\s+" . $path . "[^\\000]*?(?=^[ \\t]*\\*|\\Z)";
113 $entry =~ s/$re/\n$1/mg;