maint: update copyright
[gnulib.git] / build-aux / gitlog-to-changelog
index 0efedb0..78afff4 100755 (executable)
@@ -3,13 +3,13 @@ eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}'
     if 0;
 # Convert git log output to ChangeLog format.
 
-my $VERSION = '2012-01-06 07:14'; # UTC
+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-2012 Free Software Foundation, Inc.
+# 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
@@ -64,12 +64,21 @@ OPTIONS:
                   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
 
@@ -185,11 +194,39 @@ sub parse_amend_file($)
   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 },
@@ -198,9 +235,12 @@ sub parse_amend_file($)
      '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";
 
@@ -208,7 +248,9 @@ sub parse_amend_file($)
   # 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 = (qw (git log --log-size),
+  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"
@@ -257,6 +299,13 @@ sub parse_amend_file($)
           $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
@@ -302,13 +351,15 @@ sub parse_amend_file($)
               . substr ($_, 5) . "\n";
         }
 
-      # 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 ($date_line ne $prev_date_line
-          or "@coauthors" ne "@prev_coauthors"
-          or $multi_paragraph
-          or $prev_multi_paragraph)
+      # 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";
@@ -339,6 +390,10 @@ sub parse_amend_file($)
                 }
             }
 
+          # 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;