unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#19113: Generate a ChangeLog file from commit logs
@ 2014-11-19 23:57 Paul Eggert
  2014-11-20 15:51 ` Eli Zaretskii
                   ` (3 more replies)
  0 siblings, 4 replies; 43+ messages in thread
From: Paul Eggert @ 2014-11-19 23:57 UTC (permalink / raw)
  To: 19113

[-- Attachment #1: Type: text/plain, Size: 1202 bytes --]

Tags: patch

Attached are two patches to change the Emacs repository so that the distributed 
ChangeLog file is generated automatically from commit logs, instead of being 
maintained manually.  The first patch renames every ChangeLog file to 
ChangeLog.1 (or whatever) to get it out of the way -- that is, all existing 
ChangeLog files are retained in the repository as before.  The second patch 
arranges for the new ChangeLog file to be generated automatically from future 
commit messages.  The idea is that developers should continue to write commit 
messages in ChangeLog style, so the automatic generation is straightforward, but 
they needn't record their commit messages in ChangeLog files.  This approach was 
developed by Jim Meyering is used by several other GNU packages.

This is a first cut, and no doubt could be improved for Emacs, but I thought I'd 
start the ball rolling by publishing something that works for me.

These patches are relative to emacs-24 commit cd2e816 
<2014-11-19T19:29:40Z!eggert@cs.ucla.edu>.

PS.  The first patch would be about 12 MB, so I'm attaching an abbreviated 
summary of it instead of the actual patch; it can be reproduced using the 
summary's recipe.

[-- Attachment #2: 0001-Rename-old-ChangeLog-files-to-prepare-for-gitlog-to-.patch --]
[-- Type: text/x-diff, Size: 4876 bytes --]

From 5548379456ab22278511262e96f7938e24878e1f Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 18 Nov 2014 20:27:43 -0800
Subject: [PATCH 1/2] Rename old ChangeLog files to prepare for
 gitlog-to-changelog.

---
 ChangeLog                 | 13646 ------------------
 ChangeLog.1               | 13646 ++++++++++++++++++
 admin/ChangeLog           |  2267 ---
 admin/ChangeLog.1         |  2267 +++
 doc/emacs/ChangeLog       | 10750 ---------------
 doc/emacs/ChangeLog.1     | 10750 +++++++++++++++
 doc/lispintro/ChangeLog   |   763 --
 doc/lispintro/ChangeLog.1 |   763 ++
 doc/lispref/ChangeLog     | 13400 ------------------
 doc/lispref/ChangeLog.1   | 13400 ++++++++++++++++++
 doc/man/ChangeLog         |   183 -
 doc/man/ChangeLog.1       |   183 +
 doc/misc/ChangeLog        | 11781 ----------------
 doc/misc/ChangeLog.1      | 11781 ++++++++++++++++
 etc/ChangeLog             |  6547 ---------
 etc/ChangeLog.1           |  6547 +++++++++
 leim/ChangeLog            |  2557 ----
 leim/ChangeLog.1          |  2557 ++++
 lib-src/ChangeLog         |  8258 -----------
 lib-src/ChangeLog.1       |  8258 +++++++++++
 lisp/ChangeLog            | 16532 ----------------------
 lisp/ChangeLog.17         | 16532 ++++++++++++++++++++++
 lisp/cedet/ChangeLog      |  3088 -----
 lisp/cedet/ChangeLog.1    |  3088 +++++
 lisp/erc/ChangeLog        |   721 -
 lisp/erc/ChangeLog.09     |   721 +
 lisp/gnus/ChangeLog       | 25527 ----------------------------------
 lisp/gnus/ChangeLog.3     | 25527 ++++++++++++++++++++++++++++++++++
 lisp/mh-e/ChangeLog       |  3692 -----
 lisp/mh-e/ChangeLog.2     |  3692 +++++
 lisp/org/ChangeLog        | 32802 --------------------------------------------
 lisp/org/ChangeLog.1      | 32802 ++++++++++++++++++++++++++++++++++++++++++++
 lisp/url/ChangeLog        |  2970 ----
 lisp/url/ChangeLog.1      |  2970 ++++
 lwlib/ChangeLog           |  1878 ---
 lwlib/ChangeLog.1         |  1878 +++
 msdos/ChangeLog           |  1553 ---
 msdos/ChangeLog.1         |  1553 +++
 nextstep/ChangeLog        |   299 -
 nextstep/ChangeLog.1      |   299 +
 nt/ChangeLog              |  3443 -----
 nt/ChangeLog.1            |  3443 +++++
 oldXMenu/ChangeLog        |   684 -
 oldXMenu/ChangeLog.1      |   684 +
 src/ChangeLog             | 11230 ---------------
 src/ChangeLog.13          | 11230 +++++++++++++++
 test/ChangeLog            |  1972 ---
 test/ChangeLog.1          |  1972 +++
 48 files changed, 176543 insertions(+), 176543 deletions(-)
 delete mode 100644 ChangeLog
 create mode 100644 ChangeLog.1
 delete mode 100644 admin/ChangeLog
 create mode 100644 admin/ChangeLog.1
 delete mode 100644 doc/emacs/ChangeLog
 create mode 100644 doc/emacs/ChangeLog.1
 delete mode 100644 doc/lispintro/ChangeLog
 create mode 100644 doc/lispintro/ChangeLog.1
 delete mode 100644 doc/lispref/ChangeLog
 create mode 100644 doc/lispref/ChangeLog.1
 delete mode 100644 doc/man/ChangeLog
 create mode 100644 doc/man/ChangeLog.1
 delete mode 100644 doc/misc/ChangeLog
 create mode 100644 doc/misc/ChangeLog.1
 delete mode 100644 etc/ChangeLog
 create mode 100644 etc/ChangeLog.1
 delete mode 100644 leim/ChangeLog
 create mode 100644 leim/ChangeLog.1
 delete mode 100644 lib-src/ChangeLog
 create mode 100644 lib-src/ChangeLog.1
 delete mode 100644 lisp/ChangeLog
 create mode 100644 lisp/ChangeLog.17
 delete mode 100644 lisp/cedet/ChangeLog
 create mode 100644 lisp/cedet/ChangeLog.1
 delete mode 100644 lisp/erc/ChangeLog
 create mode 100644 lisp/erc/ChangeLog.09
 delete mode 100644 lisp/gnus/ChangeLog
 create mode 100644 lisp/gnus/ChangeLog.3
 delete mode 100644 lisp/mh-e/ChangeLog
 create mode 100644 lisp/mh-e/ChangeLog.2
 delete mode 100644 lisp/org/ChangeLog
 create mode 100644 lisp/org/ChangeLog.1
 delete mode 100644 lisp/url/ChangeLog
 create mode 100644 lisp/url/ChangeLog.1
 delete mode 100644 lwlib/ChangeLog
 create mode 100644 lwlib/ChangeLog.1
 delete mode 100644 msdos/ChangeLog
 create mode 100644 msdos/ChangeLog.1
 delete mode 100644 nextstep/ChangeLog
 create mode 100644 nextstep/ChangeLog.1
 delete mode 100644 nt/ChangeLog
 create mode 100644 nt/ChangeLog.1
 delete mode 100644 oldXMenu/ChangeLog
 create mode 100644 oldXMenu/ChangeLog.1
 delete mode 100644 src/ChangeLog
 create mode 100644 src/ChangeLog.13
 delete mode 100644 test/ChangeLog
 create mode 100644 test/ChangeLog.1

[The actual patch is about 12 MB and is elided here.
 The following shell commands implement the patch:

 find * -name ChangeLog |
 sed 's,.*,git mv & &.1,
      s, lisp/ChangeLog\.1$, lisp/ChangeLog.17,
      s, lisp/erc/ChangeLog\.1$, lisp/erc/ChangeLog.09,
      s, lisp/gnus/ChangeLog\.1$, lisp/gnus/ChangeLog.3,
      s, lisp/mh-e/ChangeLog\.1$, lisp/mh-e/ChangeLog.2,
      s, src/ChangeLog\.1$, src/ChangeLog.13,' |
 sh
 git commit -am'Rename old ChangeLog files to prepare for gitlog-to-changelog.'
]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-Generate-a-ChangeLog-file-from-commit-logs.patch --]
[-- Type: text/x-diff; name="0002-Generate-a-ChangeLog-file-from-commit-logs.patch", Size: 29830 bytes --]

From 1afc98cadae8b14e1b123765463403df4947811a Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Wed, 19 Nov 2014 14:41:42 -0800
Subject: [PATCH 2/2] Generate a ChangeLog file from commit logs.

Instead of having a ChangeLog file or files in the repository,
generate the ChangeLog file automatically from the git commit logs,
as part of the process of making a distribution.
The new procedure has been tested with vc-dwim, and this
commit was generated by vc-dwim.  Also, 'make dist woriks'.
However, I haven't tested other ways to create change log entries nor have
I tested the entire release process, and no doubt further work is needed.
* .gitignore: Add ChangeLog.
* Makefile.in (gen_start_date): New macro.
(gen-ChangeLog): New rule.
* admin/admin.el (make-manuals-dist--1):
Don't treat ChangeLog specially.
* admin/merge-gnulib (GNULIB_MODULES): Add gitlog-to-changelog.
* admin/notes/repo: Add note about vc-dwim.
* admin/admin.el (add-release-logs, make-manuals-dist--1):
* admin/make-tarball.txt, admin/notes/bugtracker:
* lisp/emacs-lisp/authors.el:
Add a FIXME comment.
* build-aux/gitlog-to-changelog: New file, from Gnulib.
* lisp/calendar/icalendar.el, lisp/gnus/deuglify.el:
* lisp/emacs-lisp/gulp.el, lwlib/README, make-dist:
Adjust to renamed old ChangeLog files.
* make-dist: Use 'make gen-ChangeLog' to build top-level
ChangeLog in the distribution.
---
 .gitignore                    |   1 +
 Makefile.in                   |  15 ++
 admin/admin.el                |   9 +-
 admin/make-tarball.txt        |   4 +
 admin/merge-gnulib            |   2 +-
 admin/notes/bugtracker        |   3 +-
 admin/notes/repo              |  13 +-
 build-aux/gitlog-to-changelog | 432 ++++++++++++++++++++++++++++++++++++++++++
 lisp/calendar/icalendar.el    |   4 +-
 lisp/emacs-lisp/authors.el    |   5 +-
 lisp/emacs-lisp/gulp.el       |   2 +-
 lisp/gnus/deuglify.el         |   2 +-
 lwlib/README                  |   2 +-
 make-dist                     |  26 ++-
 14 files changed, 497 insertions(+), 23 deletions(-)
 create mode 100755 build-aux/gitlog-to-changelog

diff --git a/.gitignore b/.gitignore
index a35ab93..53e3427 100644
--- a/.gitignore
+++ b/.gitignore
@@ -177,6 +177,7 @@ info/dir
 .#*
 
 # Git output.
+ChangeLog
 [0-9]*.patch
 
 # Distribution directories.
diff --git a/Makefile.in b/Makefile.in
index 4391c2c..b122d80 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1100,6 +1100,21 @@ bootstrap: bootstrap-clean FRC
 	$(MAKE) $(MFLAGS) MAKEFILE_NAME=force-Makefile force-Makefile
 	$(MAKE) $(MFLAGS) info all
 
+# Convert git commit log to ChangeLog file.  make-dist uses this.
+gen_start_date = 2014-11-18
+.PHONY: gen-ChangeLog
+gen-ChangeLog:
+	$(AM_V_GEN)if test -d .git; then				\
+	  log_fix="$(srcdir)/build-aux/git-log-fix";			\
+	  test -e "$$log_fix"						\
+	    && amend_git_log="--amend=$$log_fix"			\
+	    || amend_git_log=;						\
+	  $(srcdir)/build-aux/gitlog-to-changelog			\
+	    $$amend_git_log --since=$(gen_start_date) > $(distdir)/cl-t && \
+	    { rm -f $(distdir)/ChangeLog &&				\
+	      mv $(distdir)/cl-t $(distdir)/ChangeLog; }		\
+	fi
+
 .PHONY: check-declare
 
 check-declare:
diff --git a/admin/admin.el b/admin/admin.el
index 48e083d..d3aa583 100644
--- a/admin/admin.el
+++ b/admin/admin.el
@@ -28,10 +28,9 @@
 
 (defvar add-log-time-format)		; in add-log
 
-;; Does this information need to be in every ChangeLog, as opposed to
-;; just the top-level one?  Only if you allow changes the same
-;; day as the release.
-;; http://lists.gnu.org/archive/html/emacs-devel/2013-03/msg00161.html
+;; FIXME: Update this in the light of the fact that there's only
+;; one ChangeLog file now, at the top level, and it's generated from
+;; commit logs by 'make-dist'.
 (defun add-release-logs (root version &optional date)
   "Add \"Version VERSION released.\" change log entries in ROOT.
 Root must be the root of an Emacs source tree.
@@ -650,7 +649,7 @@ style=\"text-align:left\">")
     (copy-file "../doc/misc/texinfo.tex" stem)
     (or (equal type "emacs") (copy-file "../doc/emacs/emacsver.texi" stem))
     (dolist (file (directory-files (format "../doc/%s" type) t))
-      (if (or (string-match-p "\\(\\.texi\\'\\|/ChangeLog\\|/README\\'\\)" file)
+      (if (or (string-match-p "\\(\\.texi\\'\\|/README\\'\\)" file)
 	      (and (equal type "lispintro")
 		   (string-match-p "\\.\\(eps\\|pdf\\)\\'" file)))
 	  (copy-file file stem)))
diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt
index 9603c61..c080014 100644
--- a/admin/make-tarball.txt
+++ b/admin/make-tarball.txt
@@ -2,6 +2,10 @@ Instructions to create pretest or release tarballs. -*- coding: utf-8 -*-
 -- originally written by Gerd Moellmann, amended by Francesco Potortì
    with the initial help of Eli Zaretskii
 
+FIXME: There is now just one ChangeLog file, at the top level,
+generated automatically from commit logs by 'make-dist'.  The
+procedure below needs to be updated accordingly.
+
 
 Steps to take before starting on the first pretest in any release sequence:
 
diff --git a/admin/merge-gnulib b/admin/merge-gnulib
index 6c0dffb..dc33349 100755
--- a/admin/merge-gnulib
+++ b/admin/merge-gnulib
@@ -31,7 +31,7 @@ GNULIB_MODULES='
   crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512
   dtoastr dtotimespec dup2 environ execinfo faccessat
   fcntl fcntl-h fdatasync fdopendir filemode fstatat fsync
-  getloadavg getopt-gnu gettime gettimeofday
+  getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog
   intprops largefile lstat
   manywarnings memrchr mkostemp mktime
   pipe2 pselect pthread_sigmask putenv qacl readlink readlinkat
diff --git a/admin/notes/bugtracker b/admin/notes/bugtracker
index fd7bd08..9d03798 100644
--- a/admin/notes/bugtracker
+++ b/admin/notes/bugtracker
@@ -481,7 +481,8 @@ can see exactly what the fix was.
 *** bug-reference-mode
 
 Activate `bug-reference-mode' in ChangeLogs to get clickable links to
-the bug web-pages.
+the bug web-pages.  FIXME: This may need to be updated in the light of
+the new policy of just one ChangeLog, at the top level.
 
 *** Debian stuff
 
diff --git a/admin/notes/repo b/admin/notes/repo
index 46a9e08..d077896 100644
--- a/admin/notes/repo
+++ b/admin/notes/repo
@@ -37,6 +37,16 @@ NEWS, MAINTAINERS, and FOR-RELEASE, or to indicate regeneration of
 files such as 'configure'.  "There is no need" means you don't have
 to, but you can if you want to.
 
+** Using vc-dwim to maintain commit messages
+
+You can use vc-dwim to maintain commit messages in ChangeLog format.
+When you create a source directory FOO, run the shell command 'cd FOO;
+git-changelog-symlink-init' to create a symbolic link from ChangeLog
+to .git/c/ChangeLog.  Edit this ChangeLog via its symlink with Emacs
+commands like add-change-log-entry-other-window, and commit the change
+using the shell command 'cd FOO; vc-dwim'.  Type 'vc-dwim --help' for
+more info.
+
 * Commit to the right branch
 
 Development normally takes places on the trunk.
@@ -132,7 +142,8 @@ http://lists.gnu.org/archive/html/emacs-devel/2010-05/msg00262.html
 
 * How to merge changes from emacs-24 to trunk
 
-[The section on git merge procedure has not yet been written]
+[The section on git merge procedure has not yet been written.
+Among other things, the ChangeLog file is now automatically generated.]
 
 Inspect the change log entries (e.g. in case too many entries have been
 included or whitespace between entries needs fixing). If someone made
diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog
new file mode 100755
index 0000000..78afff4
--- /dev/null
+++ b/build-aux/gitlog-to-changelog
@@ -0,0 +1,432 @@
+eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
+  & eval 'exec perl -wS "$0" $argv:q'
+    if 0;
+# Convert git log output to ChangeLog format.
+
+my $VERSION = '2012-07-29 06:11'; # 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-2014 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:
+
+   --amend=FILE FILE maps from an SHA1 to perl code (i.e., s/old/new/) that
+                  makes a change to SHA1's commit log text or metadata.
+   --append-dot append a dot to the first line of each commit message if
+                  there is no other punctuation or blank at the end.
+   --no-cluster never cluster commit messages under the same date/author
+                  header; the default is to cluster adjacent commit messages
+                  if their headers are the same and neither commit message
+                  contains multiple paragraphs.
+   --srcdir=DIR the root of the source tree, from which the .git/
+                  directory can be derived.
+   --since=DATE convert only the logs since DATE;
+                  the default is to convert all log entries.
+   --format=FMT set format string for commit subject and body;
+                  see 'man git-log' for the list of format metacharacters;
+                  the default is '%s%n%b%n'
+   --strip-tab  remove one additional leading TAB from commit message lines.
+   --strip-cherry-pick  remove data inserted by "git cherry-pick";
+                  this includes the "cherry picked from commit ..." line,
+                  and the possible final "Conflicts:" paragraph.
+   --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
+
+SPECIAL SYNTAX:
+
+The following types of strings are interpreted specially when they appear
+at the beginning of a log message line.  They are not copied to the output.
+
+  Copyright-paperwork-exempt: Yes
+    Append the "(tiny change)" notation to the usual "date name email"
+    ChangeLog header to mark a change that does not require a copyright
+    assignment.
+  Co-authored-by: Joe User <user\@example.com>
+    List the specified name and email address on a second
+    ChangeLog header, denoting a co-author.
+  Signed-off-by: Joe User <user\@example.com>
+    These lines are simply elided.
+
+In a FILE specified via --amend, comment lines (starting with "#") are ignored.
+FILE must consist of <SHA,CODE+> pairs where SHA is a 40-byte SHA1 (alone on
+a line) referring to a commit in the current project, and CODE refers to one
+or more consecutive lines of Perl code.  Pairs must be separated by one or
+more blank line.
+
+Here is sample input for use with --amend=FILE, from coreutils:
+
+3a169f4c5d9159283548178668d2fae6fced3030
+# fix typo in title:
+s/all tile types/all file types/
+
+1379ed974f1fa39b12e2ffab18b3f7a607082202
+# Due to a bug in vc-dwim, I mis-attributed a patch by Paul to myself.
+# Change the author to be Paul.  Note the escaped "@":
+s,Jim .*>,Paul Eggert <eggert\\\@cs.ucla.edu>,
+
+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 $_} @_);
+}
+
+# Parse file F.
+# Comment lines (starting with "#") are ignored.
+# F must consist of <SHA,CODE+> pairs where SHA is a 40-byte SHA1
+# (alone on a line) referring to a commit in the current project, and
+# CODE refers to one or more consecutive lines of Perl code.
+# Pairs must be separated by one or more blank line.
+sub parse_amend_file($)
+{
+  my ($f) = @_;
+
+  open F, '<', $f
+    or die "$ME: $f: failed to open for reading: $!\n";
+
+  my $fail;
+  my $h = {};
+  my $in_code = 0;
+  my $sha;
+  while (defined (my $line = <F>))
+    {
+      $line =~ /^\#/
+        and next;
+      chomp $line;
+      $line eq ''
+        and $in_code = 0, next;
+
+      if (!$in_code)
+        {
+          $line =~ /^([0-9a-fA-F]{40})$/
+            or (warn "$ME: $f:$.: invalid line; expected an SHA1\n"),
+              $fail = 1, next;
+          $sha = lc $1;
+          $in_code = 1;
+          exists $h->{$sha}
+            and (warn "$ME: $f:$.: duplicate SHA1\n"),
+              $fail = 1, next;
+        }
+      else
+        {
+          $h->{$sha} ||= '';
+          $h->{$sha} .= "$line\n";
+        }
+    }
+  close F;
+
+  $fail
+    and exit 1;
+
+  return $h;
+}
+
+# git_dir_option $SRCDIR
+#
+# From $SRCDIR, the --git-dir option to pass to git (none if $SRCDIR
+# is undef).  Return as a list (0 or 1 element).
+sub git_dir_option($)
+{
+  my ($srcdir) = @_;
+  my @res = ();
+  if (defined $srcdir)
+    {
+      my $qdir = shell_quote $srcdir;
+      my $cmd = "cd $qdir && git rev-parse --show-toplevel";
+      my $qcmd = shell_quote $cmd;
+      my $git_dir = qx($cmd);
+      defined $git_dir
+        or die "$ME: cannot run $qcmd: $!\n";
+      $? == 0
+        or die "$ME: $qcmd had unexpected exit code or signal ($?)\n";
+      chomp $git_dir;
+      push @res, "--git-dir=$git_dir/.git";
+    }
+  @res;
+}
+
+{
+  my $since_date;
+  my $format_string = '%s%n%b%n';
+  my $amend_file;
+  my $append_dot = 0;
+  my $cluster = 1;
+  my $strip_tab = 0;
+  my $strip_cherry_pick = 0;
+  my $srcdir;
+  GetOptions
+    (
+     help => sub { usage 0 },
+     version => sub { print "$ME version $VERSION\n"; exit },
+     'since=s' => \$since_date,
+     'format=s' => \$format_string,
+     'amend=s' => \$amend_file,
+     'append-dot' => \$append_dot,
+     'cluster!' => \$cluster,
+     'strip-tab' => \$strip_tab,
+     'strip-cherry-pick' => \$strip_cherry_pick,
+     'srcdir=s' => \$srcdir,
+    ) or usage 1;
+
+  defined $since_date
+    and unshift @ARGV, "--since=$since_date";
+
+  # This is a hash that maps an SHA1 to perl code (i.e., s/old/new/)
+  # that makes a correction in the log or attribution of that commit.
+  my $amend_code = defined $amend_file ? parse_amend_file $amend_file : {};
+
+  my @cmd = ('git',
+             git_dir_option $srcdir,
+             qw(log --log-size),
+             '--pretty=format:%H:%ct  %an  <%ae>%n%n'.$format_string, @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_multi_paragraph;
+  my $prev_date_line = '';
+  my @prev_coauthors = ();
+  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";
+
+      # Extract leading hash.
+      my ($sha, $rest) = split ':', $log, 2;
+      defined $sha
+        or die "$ME:$.: malformed log entry\n";
+      $sha =~ /^[0-9a-fA-F]{40}$/
+        or die "$ME:$.: invalid SHA1: $sha\n";
+
+      # If this commit's log requires any transformation, do it now.
+      my $code = $amend_code->{$sha};
+      if (defined $code)
+        {
+          eval 'use Safe';
+          my $s = new Safe;
+          # Put the unpreprocessed entry into "$_".
+          $_ = $rest;
+
+          # Let $code operate on it, safely.
+          my $r = $s->reval("$code")
+            or die "$ME:$.:$sha: failed to eval \"$code\":\n$@\n";
+
+          # Note that we've used this entry.
+          delete $amend_code->{$sha};
+
+          # Update $rest upon success.
+          $rest = $_;
+        }
+
+      # Remove lines inserted by "git cherry-pick".
+      if ($strip_cherry_pick)
+        {
+          $rest =~ s/^\s*Conflicts:\n.*//sm;
+          $rest =~ s/^\s*\(cherry picked from commit [\da-f]+\)\n//m;
+        }
+
+      my @line = split "\n", $rest;
+      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";
+
+      # Format 'Copyright-paperwork-exempt: Yes' as a standard ChangeLog
+      # `(tiny change)' annotation.
+      my $tiny = (grep (/^Copyright-paperwork-exempt:\s+[Yy]es$/, @line)
+                  ? '  (tiny change)' : '');
+
+      my $date_line = sprintf "%s  %s$tiny\n",
+        strftime ("%F", localtime ($1)), $2;
+
+      my @coauthors = grep /^Co-authored-by:.*$/, @line;
+      # Omit meta-data lines we've already interpreted.
+      @line = grep !/^(?:Signed-off-by:[ ].*>$
+                       |Co-authored-by:[ ]
+                       |Copyright-paperwork-exempt:[ ]
+                       )/x, @line;
+
+      # Remove leading and trailing blank lines.
+      if (@line)
+        {
+          while ($line[0] =~ /^\s*$/) { shift @line; }
+          while ($line[$#line] =~ /^\s*$/) { pop @line; }
+        }
+
+      # Record whether there are two or more paragraphs.
+      my $multi_paragraph = grep /^\s*$/, @line;
+
+      # Format 'Co-authored-by: A U Thor <email@example.com>' lines in
+      # standard multi-author ChangeLog format.
+      for (@coauthors)
+        {
+          s/^Co-authored-by:\s*/\t    /;
+          s/\s*</  </;
+
+          /<.*?@.*\..*>/
+            or warn "$ME: warning: missing email address for "
+              . substr ($_, 5) . "\n";
+        }
+
+      # If clustering of commit messages has been disabled, if this header
+      # would be different from the previous date/name/email/coauthors header,
+      # or if this or the previous entry consists of two or more paragraphs,
+      # then print the header.
+      if ( ! $cluster
+          || $date_line ne $prev_date_line
+          || "@coauthors" ne "@prev_coauthors"
+          || $multi_paragraph
+          || $prev_multi_paragraph)
+        {
+          $prev_date_line eq ''
+            or print "\n";
+          print $date_line;
+          @coauthors
+            and print join ("\n", @coauthors), "\n";
+        }
+      $prev_date_line = $date_line;
+      @prev_coauthors = @coauthors;
+      $prev_multi_paragraph = $multi_paragraph;
+
+      # If there were any lines
+      if (@line == 0)
+        {
+          warn "$ME: warning: empty commit message:\n  $date_line\n";
+        }
+      else
+        {
+          if ($append_dot)
+            {
+              # If the first line of the message has enough room, then
+              if (length $line[0] < 72)
+                {
+                  # append a dot if there is no other punctuation or blank
+                  # at the end.
+                  $line[0] =~ /[[:punct:]\s]$/
+                    or $line[0] .= '.';
+                }
+            }
+
+          # Remove one additional leading TAB from each line.
+          $strip_tab
+            and map { s/^\t// } @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
+
+  # Complain about any unused entry in the --amend=F specified file.
+  my $fail = 0;
+  foreach my $sha (keys %$amend_code)
+    {
+      warn "$ME:$amend_file: unused entry: $sha\n";
+      $fail = 1;
+    }
+
+  exit $fail;
+}
+
+# Local Variables:
+# mode: perl
+# 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:
diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el
index 4ba4869..18aeb61 100644
--- a/lisp/calendar/icalendar.el
+++ b/lisp/calendar/icalendar.el
@@ -39,7 +39,7 @@
 
 ;;; History:
 
-;;  0.07 onwards: see lisp/ChangeLog
+;;  0.07 onwards: see commit logs and ../ChangeLog*.
 
 ;;  0.06:  (2004-10-06)
 ;;  - Bugfixes regarding icalendar-import-format-*.
@@ -1047,7 +1047,7 @@ FExport diary data into iCalendar file: ")
 
                 (setq header (concat "\nBEGIN:VEVENT\nUID:"
                                      (or uid
-                                         (icalendar--create-uid entry-full 
+                                         (icalendar--create-uid entry-full
                                                                 contents)))))
               (setq result (concat result header contents "\nEND:VEVENT")))
           ;; handle errors
diff --git a/lisp/emacs-lisp/authors.el b/lisp/emacs-lisp/authors.el
index 51bd415..c53feee 100644
--- a/lisp/emacs-lisp/authors.el
+++ b/lisp/emacs-lisp/authors.el
@@ -27,6 +27,9 @@
 ;; Use M-x authors RET to create an *Authors* buffer that can used as
 ;; or merged with Emacs's AUTHORS file.
 
+;; FIXME: This needs to modernized in the light of current practice,
+;; which generates a single top-level ChangeLog file from commit logs.
+
 ;;; Code:
 
 (defvar authors-coding-system 'utf-8
@@ -75,7 +78,7 @@ files.")
     ("Gerd Möllmann" "Gerd Moellmann")
     ("Hallvard B. Furuseth" "Hallvard B Furuseth" "Hallvard Furuseth")
     ("Hrvoje Nikšić" "Hrvoje Niksic")
-    ;; lisp/org/ChangeLog 2010-11-11.
+    ;; lisp/org/ChangeLog.1 2010-11-11.
     (nil "aaa bbb")
     (nil "Code Extracted") ; lisp/newcomment.el's "Author:" header
     ("Jaeyoun Chung" "Jae-youn Chung" "Jae-you Chung" "Chung Jae-youn")
diff --git a/lisp/emacs-lisp/gulp.el b/lisp/emacs-lisp/gulp.el
index d0a89b3..2d0314b 100644
--- a/lisp/emacs-lisp/gulp.el
+++ b/lisp/emacs-lisp/gulp.el
@@ -69,7 +69,7 @@ please send them to me ASAP.
 Please don't send the whole file.  Instead, please send a patch made with
 `diff -c' that shows precisely the changes you would like me to install.
 Also please include itemized change log entries for your changes;
-please use lisp/ChangeLog as a guide for the style and for what kinds
+please use lisp/ChangeLog* as a guide for the style and for what kinds
 of information to include.
 
 Thanks.")
diff --git a/lisp/gnus/deuglify.el b/lisp/gnus/deuglify.el
index 7a0f613..a28a255 100644
--- a/lisp/gnus/deuglify.el
+++ b/lisp/gnus/deuglify.el
@@ -188,7 +188,7 @@
 ;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;
-;; See ChangeLog for other changes.
+;; See commit log or ChangeLog* for other changes.
 ;;
 ;; Revision 1.5  2002/01/27 14:39:17  rscholz
 ;; * New variable `gnus-outlook-deuglify-no-wrap-chars' to inhibit
diff --git a/lwlib/README b/lwlib/README
index 25c72eb..ed7583d 100644
--- a/lwlib/README
+++ b/lwlib/README
@@ -4,4 +4,4 @@ library was written by Lucid, Inc and released under the terms of the
 GPL version 1 (or later).  It is not considered part of GNU Emacs.
 
 This version of the library differs from the original as described in
-the ChangeLog file.
+the ChangeLog.1 file.
diff --git a/make-dist b/make-dist
index aed5b17..ab3b6e4 100755
--- a/make-dist
+++ b/make-dist
@@ -278,13 +278,20 @@ fi
 echo "Creating top directory: \`${tempdir}'"
 mkdir ${tempdir}
 
+if test -d .git; then
+  echo "Making top-level ChangeLog"
+  make distdir=${tempdir} gen-ChangeLog
+else
+  echo "No repository, so omitting top-level ChangeLog"
+fi
+
 ### We copy in the top-level files before creating the subdirectories in
 ### hopes that this will make the top-level files appear first in the
 ### tar file; this means that people can start reading the INSTALL and
 ### README while the rest of the tar file is still unpacking.  Whoopee.
 echo "Making links to top-level files"
 ln INSTALL README BUGS ${tempdir}
-ln ChangeLog Makefile.in autogen.sh configure configure.ac ${tempdir}
+ln ChangeLog.*[0-9] Makefile.in autogen.sh configure configure.ac ${tempdir}
 ln config.bat make-dist .dir-locals.el ${tempdir}
 ln aclocal.m4 ${tempdir}
 
@@ -334,7 +341,7 @@ done
 echo "Making links to \`leim' and its subdirectories"
 (cd leim
  ln makefile.w32-in ../${tempdir}/leim
- ln ChangeLog README ../${tempdir}/leim
+ ln ChangeLog.*[0-9] README ../${tempdir}/leim
  ln CXTERM-DIC/README CXTERM-DIC/*.tit ../${tempdir}/leim/CXTERM-DIC
  ln SKK-DIC/README SKK-DIC/SKK-JISYO.L ../${tempdir}/leim/SKK-DIC
  ln MISC-DIC/README MISC-DIC/*.* ../${tempdir}/leim/MISC-DIC
@@ -345,6 +352,7 @@ echo "Making links to \`leim' and its subdirectories"
 echo "Making links to \`build-aux'"
 (cd build-aux
  ln compile config.guess config.sub depcomp msys-to-w32 ../${tempdir}/build-aux
+ ln gitlog-to-changelog ../${tempdir}/build-aux
  ln install-sh missing move-if-change ../${tempdir}/build-aux
  ln update-copyright update-subdirs ../${tempdir}/build-aux
  ln dir_top make-info-dir ../${tempdir}/build-aux)
@@ -361,7 +369,7 @@ echo "Making links to \`src'"
  ln [a-zA-Z]*.[chm] ../${tempdir}/src
  ln [a-zA-Z]*.in ../${tempdir}/src
  ln [a-zA-Z]*.mk ../${tempdir}/src
- ln README ChangeLog ChangeLog.*[0-9] ../${tempdir}/src
+ ln README ChangeLog.*[0-9] ../${tempdir}/src
  ln makefile.w32-in ../${tempdir}/src
  ln .gdbinit .dbxinit ../${tempdir}/src
  cd ../${tempdir}/src
@@ -383,7 +391,7 @@ echo "Making links to \`lib'"
 echo "Making links to \`lib-src'"
 (cd lib-src
  ln [a-zA-Z]*.[ch] ../${tempdir}/lib-src
- ln ChangeLog Makefile.in README testfile ../${tempdir}/lib-src
+ ln ChangeLog.*[0-9] Makefile.in README testfile ../${tempdir}/lib-src
  ln grep-changelog rcs2log ../${tempdir}/lib-src
  ln makefile.w32-in ../${tempdir}/lib-src
  ln update-game-score.exe.manifest ../${tempdir}/lib-src)
@@ -399,7 +407,7 @@ echo "Making links to \`nt'"
  ln nmake.defs gmake.defs subdirs.el [a-z]*.bat [a-z]*.[ch] ../${tempdir}/nt
  ln Makefile.in gnulib.mk ../${tempdir}/nt
  ln mingw-cfg.site epaths.nt INSTALL.OLD ../${tempdir}/nt
- ln ChangeLog INSTALL README README.W32 makefile.w32-in ../${tempdir}/nt)
+ ln ChangeLog.*[0-9] INSTALL README README.W32 makefile.w32-in ../${tempdir}/nt)
 
 echo "Making links to \`nt/inc' and its subdirectories"
 for f in `find nt/inc -type f -name '[a-z]*.h'`; do
@@ -413,13 +421,13 @@ echo "Making links to \`nt/icons'"
 
 echo "Making links to \`msdos'"
 (cd msdos
- ln ChangeLog INSTALL README emacs.ico emacs.pif ../${tempdir}/msdos
+ ln ChangeLog.*[0-9] INSTALL README emacs.ico emacs.pif ../${tempdir}/msdos
  ln depfiles.bat inttypes.h ../${tempdir}/msdos
  ln is_exec.c sigaction.c mainmake.v2 sed*.inp ../${tempdir}/msdos)
 
 echo "Making links to \`nextstep'"
 (cd nextstep
- ln ChangeLog README INSTALL Makefile.in ../${tempdir}/nextstep)
+ ln ChangeLog.*[0-9] README INSTALL Makefile.in ../${tempdir}/nextstep)
 
 echo "Making links to \`nextstep/templates'"
 (cd nextstep/templates
@@ -440,12 +448,12 @@ echo "Making links to \`nextstep/GNUstep/Emacs.base/Resources'"
 echo "Making links to \`oldXMenu'"
 (cd oldXMenu
  ln *.[ch] *.in ../${tempdir}/oldXMenu
- ln README ChangeLog ../${tempdir}/oldXMenu)
+ ln README ChangeLog.*[0-9] ../${tempdir}/oldXMenu)
 
 echo "Making links to \`lwlib'"
 (cd lwlib
  ln *.[ch] *.in ../${tempdir}/lwlib
- ln README ChangeLog ../${tempdir}/lwlib)
+ ln README ChangeLog.*[0-9] ../${tempdir}/lwlib)
 
 ## It is important to distribute admin/ because it contains sources
 ## for generated lisp/international/uni-*.el files.
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2015-04-07  7:06 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-19 23:57 bug#19113: Generate a ChangeLog file from commit logs Paul Eggert
2014-11-20 15:51 ` Eli Zaretskii
2014-11-20 17:43   ` Paul Eggert
2014-11-20 17:44   ` Paul Eggert
2014-11-26  5:38     ` Paul Eggert
2014-11-26  6:21       ` Jan D.
2014-11-26  7:50         ` Paul Eggert
2014-11-26 15:12       ` Stefan Monnier
2014-11-26 19:16         ` Paul Eggert
2014-11-26 22:15           ` Stefan Monnier
2014-12-05  8:07           ` Glenn Morris
2014-12-05  8:38             ` Eli Zaretskii
2014-12-05 14:33             ` Ted Zlatanov
2014-12-05 18:49               ` Stefan Monnier
2014-12-05 20:08                 ` Ted Zlatanov
2014-12-06  4:59                   ` Stefan Monnier
2014-12-06 13:17                     ` Ted Zlatanov
2014-12-06  2:27                 ` Dmitry Gutov
2014-12-06  5:06                   ` Stefan Monnier
2014-12-06  7:26                     ` Eli Zaretskii
2014-12-09 13:46                     ` Dmitry Gutov
2014-12-05 15:38             ` Stefan Monnier
2014-12-06  4:42               ` Paul Eggert
2014-12-06  7:40                 ` Eli Zaretskii
2014-12-09  5:14                 ` Glenn Morris
2014-12-09  6:42                   ` Paul Eggert
2015-01-03  1:37             ` Glenn Morris
2014-11-20 18:00   ` Achim Gratz
2014-11-20 17:25 ` Pádraig Brady
2015-01-12  7:38 ` Paul Eggert
2015-01-15 14:58   ` Stefan Monnier
2015-01-15 21:46   ` Glenn Morris
2015-01-16  1:27     ` Paul Eggert
2015-01-30 16:34       ` Stefan Monnier
2015-01-30 20:14         ` Paul Eggert
2015-01-31  6:33           ` Stefan Monnier
2015-01-31  8:18             ` Paul Eggert
2015-01-31  9:06           ` Andreas Schwab
2015-03-21  2:37 ` Paul Eggert
2015-03-21  8:33   ` Eli Zaretskii
2015-03-21 14:38     ` Stefan Monnier
2015-03-22 23:53   ` Glenn Morris
2015-04-07  7:06   ` Paul Eggert

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).