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 # do not delete or rename directories from the list as long as
70 # Changelog entries referring to them exist!
71 remove_parts
(qw( contrib/ testing/ xemacs/ mk/ etc/ ));
72 remove_parts
(qw( .*Makefile README .+\.mk ));
74 if ($kind eq "lisp") { remove_parts
("doc/") }
75 if ($kind eq "texi") { remove_parts
("lisp/","doc/orgcard","doc/orgguide") }
76 if ($kind eq "card") { remove_parts
("lisp/","doc/org\\.","doc/orgguide") }
78 # remove/replace parts of the path
79 $entry =~ s
:^\
* lisp
/:* :mg
;
80 $entry =~ s
:^\
* doc
/orgcard:* refcards/orgcard
:mg
;
81 $entry =~ s
:^\
* doc
/:* misc/:mg
;
83 # remove empty space at beginning and end
87 # remove everything that is not a starred entry
88 my @entries = grep( /^\*/, split( /\n\n/, $entry ));
90 # If there is anything left in the entry, print it
91 if (scalar @entries) {
92 push @
{ $entries{"$syncdate $name $address$tiny"} }, @entries;
96 foreach my $key ( sort keys %entries ) {
97 next if (! exists $entries{"$key"} );
99 if ( exists $entries{"$key (tiny change)"} ) {
100 push @
{ $entries{"$key"} }, @
{ $entries{"$key (tiny change)"} };
101 delete $entries{"$key (tiny change)"};
103 my @entries = @
{ $entries{"$key"} };
104 foreach my $entry ( @entries ) {
105 # indent each line by exactly one TAB
114 $re = "^[ \t]*\\*\\s+" . $path . "[^\\000]*?(?=^[ \\t]*\\*|\\Z)";
115 $entry =~ s/$re/\n$1/mg;