Generate ChangeLog from git log

* .gitignore: Add ChangeLog
* ChangeLog: Rename to ChangeLog-CVS.
* Makefile.am (gen-changelog): New rule.
(dist-hook): Depend on it.
(EXTRA_DIST): Add ChangeLog-CVS.
* README-hacking: Describe changes.
* gitlog-to-changelog: Import from gnulib.

Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
This commit is contained in:
Дмитрий Левин 2009-07-09 00:47:41 +00:00
parent 414fe7d4d2
commit 08f922a574
5 changed files with 216 additions and 2 deletions

2
.gitignore vendored
View File

@ -4,6 +4,8 @@
.libs
.*.swp
ChangeLog
Makefile
Makefile.in

View File

@ -24,7 +24,7 @@ EXTRA_DIST = $(man_MANS) errnoent.sh signalent.sh syscallent.sh ioctlsort.c \
debian/strace.docs debian/strace.examples debian/strace.install \
debian/strace.manpages debian/strace-udeb.install \
strace.spec \
strace-graph COPYRIGHT CREDITS PORTING \
strace-graph ChangeLog-CVS COPYRIGHT CREDITS PORTING \
README-freebsd README-linux README-sunos4 README-svr4 \
linux/ioctlsort.c linux/ioctlent.sh \
linux/ioctlent.h linux/errnoent.h linux/signalent.h \
@ -83,6 +83,16 @@ EXTRA_DIST = $(man_MANS) errnoent.sh signalent.sh syscallent.sh ioctlsort.c \
svr4/signalent.h svr4/syscall.h svr4/syscallent.h \
xlate.el
gen_changelog_start_date = 2009-07-09
gen-changelog:
if test -d .git; then \
$(top_srcdir)/gitlog-to-changelog \
--since=$(gen_changelog_start_date) \
> $(distdir)/ChangeLog; \
fi
dist-hook: gen-changelog
.PHONY: gen-changelog
if MAINTAINER_MODE
if LINUX

View File

@ -1,5 +1,24 @@
Requirements
============
If you use the GIT version of strace there will be some files missing
that you need to build strace. These files are generated by tools from
the GNU Autoconf and Automake packages. You need recent versions, which
provide the `autoreconf -i' command that will do everything you need.
No more ChangeLog file
======================
Do not create or modify the ChangeLog files. Starting at 2009-07-09, the
policy changed. Before, we would insert the exact same text (or worse,
sometimes slightly differing) into both the ChangeLog file and the commit
log. Now we put that information only in the commit log, and generate
the top-level ChangeLog file from logs at "make dist" time. As such,
there are strict requirements on the form of the commit log messages.
Commit log requirements
=======================
Each commit log should always start with a one-line summary, the second
line should be blank, and the remaining lines are usually ChangeLog-style
entries for all affected files, except the leading TABs which should
be omitted.

183
gitlog-to-changelog Executable file
View File

@ -0,0 +1,183 @@
#!/usr/bin/perl
# Convert git log output to ChangeLog format.
my $VERSION = '2009-06-04 08:53'; # UTC
# The definition above must lie within the first 8 lines in order
# for the Emacs time-stamp write hook (at end) to update it.
# If you change this file with Emacs, please let the write hook
# do its job. Otherwise, update this string manually.
# Copyright (C) 2008, 2009 Free Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# Written by Jim Meyering
use strict;
use warnings;
use Getopt::Long;
use POSIX qw(strftime);
(my $ME = $0) =~ s|.*/||;
# use File::Coda; # http://meyering.net/code/Coda/
END {
defined fileno STDOUT or return;
close STDOUT and return;
warn "$ME: failed to close standard output: $!\n";
$? ||= 1;
}
sub usage ($)
{
my ($exit_code) = @_;
my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
if ($exit_code != 0)
{
print $STREAM "Try `$ME --help' for more information.\n";
}
else
{
print $STREAM <<EOF;
Usage: $ME [OPTIONS] [ARGS]
Convert git log output to ChangeLog format. If present, any ARGS
are passed to "git log". To avoid ARGS being parsed as options to
$ME, they may be preceded by '--'.
OPTIONS:
--since=DATE convert only the logs since DATE;
the default is to convert all log entries.
--help display this help and exit
--version output version information and exit
EXAMPLE:
$ME --since=2008-01-01 > ChangeLog
$ME -- -n 5 foo > last-5-commits-to-branch-foo
EOF
}
exit $exit_code;
}
# If the string $S is a well-behaved file name, simply return it.
# If it contains white space, quotes, etc., quote it, and return the new string.
sub shell_quote($)
{
my ($s) = @_;
if ($s =~ m![^\w+/.,-]!)
{
# Convert each single quote to '\''
$s =~ s/\'/\'\\\'\'/g;
# Then single quote the string.
$s = "'$s'";
}
return $s;
}
sub quoted_cmd(@)
{
return join (' ', map {shell_quote $_} @_);
}
{
my $since_date = '1970-01-01 UTC';
GetOptions
(
help => sub { usage 0 },
version => sub { print "$ME version $VERSION\n"; exit },
'since=s' => \$since_date,
) or usage 1;
my @cmd = (qw (git log --log-size), "--since=$since_date",
'--pretty=format:%ct %an <%ae>%n%n%s%n%b%n', @ARGV);
open PIPE, '-|', @cmd
or die ("$ME: failed to run `". quoted_cmd (@cmd) ."': $!\n"
. "(Is your Git too old? Version 1.5.1 or later is required.)\n");
my $prev_date_line = '';
while (1)
{
defined (my $in = <PIPE>)
or last;
$in =~ /^log size (\d+)$/
or die "$ME:$.: Invalid line (expected log size):\n$in";
my $log_nbytes = $1;
my $log;
my $n_read = read PIPE, $log, $log_nbytes;
$n_read == $log_nbytes
or die "$ME:$.: unexpected EOF\n";
my @line = split "\n", $log;
my $author_line = shift @line;
defined $author_line
or die "$ME:$.: unexpected EOF\n";
$author_line =~ /^(\d+) (.*>)$/
or die "$ME:$.: Invalid line "
. "(expected date/author/email):\n$author_line\n";
my $date_line = sprintf "%s $2\n", strftime ("%F", localtime ($1));
# If this line would be the same as the previous date/name/email
# line, then arrange not to print it.
if ($date_line ne $prev_date_line)
{
$prev_date_line eq ''
or print "\n";
print $date_line;
}
$prev_date_line = $date_line;
# Omit "Signed-off-by..." lines.
@line = grep !/^Signed-off-by: .*>$/, @line;
# If there were any lines
if (@line == 0)
{
warn "$ME: warning: empty commit message:\n $date_line\n";
}
else
{
# Remove leading and trailing blank lines.
while ($line[0] =~ /^\s*$/) { shift @line; }
while ($line[$#line] =~ /^\s*$/) { pop @line; }
# Prefix each non-empty line with a TAB.
@line = map { length $_ ? "\t$_" : '' } @line;
print "\n", join ("\n", @line), "\n";
}
defined ($in = <PIPE>)
or last;
$in ne "\n"
and die "$ME:$.: unexpected line:\n$in";
}
close PIPE
or die "$ME: error closing pipe from " . quoted_cmd (@cmd) . "\n";
# FIXME-someday: include $PROCESS_STATUS in the diagnostic
}
# Local Variables:
# indent-tabs-mode: nil
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "my $VERSION = '"
# time-stamp-format: "%:y-%02m-%02d %02H:%02M"
# time-stamp-time-zone: "UTC"
# time-stamp-end: "'; # UTC"
# End: