2 # Copyright © 2013,2014 Géraud Meyer <graud@gmx.com>
4 # This program is free software; you can redistribute it and/or modify it under
5 # the terms of the GNU General Public License version 2 as published by the
6 # Free Software Foundation.
8 # This program is distributed in the hope that it will be useful, but WITHOUT
9 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 # You should have received a copy of the GNU General Public License along with
14 # this program. If not, see <http://www.gnu.org/licenses/>.
16 PROGRAM_NAME
="gitchangelog.sh"
21 gitchangelog.sh - portable script generating a GNU-like changelog from a Git log
23 gitchangelog.sh [<options>] [--] [ {-|<outfile>} [<git_log_args>] ]
24 gitchangelog.sh [<options>] [--] {-|<outfile>} -
27 Prepend changelog entries by tag names in brackets.
28 --tag-pattern <sed_BRE>
29 Tags to consider for marking entries. The pattern should not match
30 across spaces; the default is "[^ ]\{1,\}".
32 Prepend changelog entries by merge marks.
34 Only keep the title of a commit. This implies --title-star, that can
35 be disabled by a supplemental --git-body.
37 Prepend the title by a star as is done with the other parapgraphs.
39 Do not reformat the commit message, only reindent it.
41 Do not separate the title from the rest by a blank line.
50 Each commit message is made into a changelog entry. Each paragraph of a
51 Git commit message body is made into a star item of the changelog. The
52 message title is kept on a separate line. Text lines are never broken nor
55 By default git is run to get the log
, with the required options. If a dash
56 is given
in place of additional
<git_log_args
>, then the log is
read from
57 the standard input
; in that
case pass the option
--date=short and possibly
58 also
--decorate to git to get the appropriate log format.
60 The
script is portable to POSIX sh and to other
less comformant shells such
63 The
sed code is portable to POSIX
sed but requires only Simple Regular
64 Expressions
(SRE
) instead of Basic Regular Expressions
(BRE
) which makes it
65 prone to work under Solaris and old BSDs. git-log is required
if the log
66 is not
read from stdin.
68 $ .
/gitchangelog.sh
--title-star --no-blankline GNUChangeLog
69 $ .
/gitchangelog.sh
--tags --tag-pattern 'release\/[^ ]*' -- - --date-order |
70 sed 's/^\[release/^L\[release/' > ChangeLog
71 $ git log
--date=short
--decorate --first-parent |
72 .
/gitchangelog.sh
--merge ChangeLog
-
74 gitchangelog.sh was written by G.raud Meyer.
81 GITBODY
= NO_GITBODY
=yes
94 shift; TAG_PATTERN
=${1-} ;;
98 TITLE
=yes NO_TITLE
= TITLESTAR
=yes ;;
102 GITBODY
=yes NO_GITBODY
= ;;
106 echo "$PROGRAM_NAME version $PROGRAM_VERSION"
111 help_message
; exit ;;
113 echo "$0: unknown option $1" >&2
123 [ -n "$TAGS" ] ||
[ -n "$MERGE" ] && ANNOTATE
=yes
124 # git repository check
125 test x
"${2-}" != x
"-" &&
126 if test -d .git || git rev-parse
--git-dir >/dev
/null
129 echo "$0: error not in a git repository" >&2
135 test x
"${1-}" != x
"-" &&
143 # Some shells, like the family of pdksh, behave differently regarding
144 # the backslash in variable substitutions inside a here document.
147 # pdksh and posh do not keep a newline preceded by a backslash inside a
148 # single quoted string inside two levels of command substitution (when the
149 # second level is double quoted).
150 exec 4>&1 # to pass stdout to the following process substitution
151 eval "$( exec 3>&1 1>&4 4>&- # eval will set $gitrc and $rc
152 if test x"${1-}" = x"-"
153 then cat; echo >&3 gitrc=$?
154 else git log --date=short ${ANNOTATE:+--decorate} ${1+"$@"}; echo >&3 gitrc=$?
157 LC_ALL=C sed -e "$(# Transform the GNU sed program into a more portable one
158 LC_ALL=C sed -e 's
/\\s
/[ \\t
]/g
164 # Put the tags in the hold space
167 s
/^commit
[a-zA-Z0-9
]\
+//; s
/^ \
+(\
(.
*\
))\$
/, \
1/
169 # conditionnal branch to reset
170 ${TAGS:+t a;} s
/.
*//; t e
171 # extract the desired tags
173 s
/\
(.
*\
)\n tag
: \
($TAG_PATTERN\
)\$
/[\
2]@n\
1/; t a
174 s
/\
(.
*\
)\n [^
]*\$
/\
1/; t a
175 s
/\
(.
*\
)\n [a-zA-Z
]\
+: *[^
]*\$
/\
1/; t a
178 # Add the merge marker to the hold space
179 /^Merge
: / { ${MERGE:+x; s/\$/${B}M$b /; x;} d
; }
181 # Process author, date, tag
182 ${ANNOTATE:+x; s/${s}s*\$/@n/; x; b s;} x
; s
/.
*/@n
/; x
${ANNOTATE:+; :s}
183 N
; G
; s
/^Author
:\s
*\
(.
*\
) \s
*\
(<[^
<>]*>\
)\s
*\nDate
:\s
*\
(.
*\
)\n\
(.
*\n\
)\$
/\
4\
3 \
1 \
2@n
/
186 n
; N
; s
/^.
*\n /\t${TITLESTAR:+${NO_GITBODY:+* }}/
187 t t
; :t
; n
; s
/^ \
(.\
+\
)\$
/\t${TITLESTAR:+${NO_GITBODY:+ }}\
1/; t t
188 # If non empty body, print an extra line
189 ${NO_TITLE:+${NO_GITBODY:+${BLANKLINE:+/^\$/ !$B s/^ /${s}t/p; s/^${s}t/ /; $b}}}
192 # First line of the paragraph
193 :b
; /^ \$
/ { N
; s
/^
\n//; s
/^ \
(.\
)/${GITBODY:+${s}t@n}\t${NO_GITBODY:+* }\1/; b b; }
194 # Rest of the paragraph
195 s
/^
/\t${NO_GITBODY:+ }/
196 # Reset the hold space for the next entry
206 echo >&2 "$0: ERROR git or cat failed with #$gitrc"
208 { echo >&2 "$0: ERROR sed failed with #$rc"; exit $rc; }