Merge pull request #325 from markeissler/better-changelog

Complete rewrite to support commit ranges for pretty and list output.
This commit is contained in:
hemanth.hm 2015-03-12 11:38:08 +05:30
commit e4ea8690db
5 changed files with 520 additions and 129 deletions

View file

@ -13,6 +13,7 @@ Maintainer
Patches and Suggestions
```````````````````````
- Mark Eissler
- Kenneth Reitz
- Aggelos Orfanakos
- Jonathan "Duke" Leto

View file

@ -1,59 +1,307 @@
#!/usr/bin/env bash
FILE=""
LIST=false
TAG="n.n.n"
GIT_LOG_OPTS=$(git config changelog.opts)
GIT_LOG_FORMAT=$(git config changelog.format)
test -z "$GIT_LOG_FORMAT" && GIT_LOG_FORMAT=' * %s'
EDITOR=$(git var GIT_EDITOR)
DEF_TAG_RECENT="n.n.n"
GIT_LOG_OPTS="$(git config changelog.opts)"
GIT_LOG_FORMAT="$(git config changelog.format)"
[[ -z "$GIT_LOG_FORMAT" ]] && GIT_LOG_FORMAT=' * %s'
GIT_EDITOR="$(git var GIT_EDITOR)"
PROGNAME="git-changelog"
while [ "$1" != "" ]; do
case $1 in
-l | --list )
LIST=true
;;
-t | --tag )
TAG=$2
shift
;;
--no-merges )
GIT_LOG_OPTS='--no-merges'
;;
* )
FILE=$1
;;
esac
shift
done
_usage() {
cat << EOF
usage: $PROGNAME options [file]
usage: $PROGNAME -h|help|?
if $LIST; then
lasttag=$(git rev-list --tags --max-count=1 2>/dev/null)
version=$(git describe --tags --abbrev=0 $lasttag 2>/dev/null)
if test -z "$version"; then
Generate a Changelog from git(1) tags (annotated or lightweight) and commit
messages. Existing Changelog files with filenames that begin with 'Change' or
'History' will be identified automatically and their content will be appended
to the new output generated (unless the -p|--prune-old option is used). If no
tags exist, then all commits are output; if tags exist, then only the most-
recent commits are output up to the last identified tag.
OPTIONS:
-a, --all Retrieve all commits (ignores --start-tag, --final-tag)
-l, --list Display commits as a list, with no titles
-t, --tag Tag label to use for most-recent (untagged) commits
-f, --final-tag Newest tag to retrieve commits from in a range
-s, --start-tag Oldest tag to retrieve commits from in a range
-n, --no-merges Suppress commits from merged branches
-p, --prune-old Replace existing Changelog entirely with new content
-x, --stdout Write output to stdout instead of to a Changelog file
-h, --help, ? Show this message
EOF
}
_error() {
[ $# -eq 0 ] && _usage && exit 0
echo
echo "ERROR: " "$@"
echo
}
_fetchCommitRange() {
local list_all="${1:-false}"
local start_tag="$2"
local final_tag="$3"
if [[ "$list_all" == true ]]; then
git log $GIT_LOG_OPTS --pretty=format:"${GIT_LOG_FORMAT}"
else
git log $GIT_LOG_OPTS --pretty=format:"${GIT_LOG_FORMAT}" $version..
elif [[ -n "$final_tag" && "$start_tag" == "null" ]]; then
git log $GIT_LOG_OPTS --pretty=format:"${GIT_LOG_FORMAT}" "${final_tag}"
elif [[ -n "$final_tag" ]]; then
git log $GIT_LOG_OPTS --pretty=format:"${GIT_LOG_FORMAT}" "${start_tag}"'..'"${final_tag}"
elif [[ -n "$start_tag" ]]; then
git log $GIT_LOG_OPTS --pretty=format:"${GIT_LOG_FORMAT}" "${start_tag}"'..'
fi | sed 's/^ \* \*/ */g'
exit
fi
}
DATE=`date +'%Y-%m-%d'`
HEAD="\n$TAG / $DATE\n"
for i in $(seq 5 ${#HEAD}); do HEAD="$HEAD="; done
HEAD="$HEAD\n\n"
_formatCommitPlain() {
local start_tag="$1"
local final_tag="$2"
CHANGELOG=$FILE
if test "$CHANGELOG" = ""; then
CHANGELOG=`ls | egrep 'change|history' -i|head -n1`
if test "$CHANGELOG" = ""; then
CHANGELOG='History.md';
printf "%s" "$(_fetchCommitRange "false" "$start_tag" "$final_tag")"
}
_formatCommitPretty() {
local title_tag="$1"
local title_date="$2"
local start_tag="$3"
local final_tag="$4"
local title="$title_tag / $title_date"
local title_underline=""
local i
for i in $(seq ${#title}); do
title_underline+="="
done
unset i
printf '\n%s\n%s\n' "$title" "$title_underline"
printf "\n%s\n" "$(_fetchCommitRange "false" "$start_tag" "$final_tag")"
}
commitList() {
# parameter list supports empty arguments!
local list_all="${1:-false}"; shift
local title_tag="$1"; shift
local start_tag="$1"; shift
local final_tag="$1"; shift
local list_style="${1:-false}" # enable/disable list format
local changelog="$FILE"
local title_date="$(date +'%Y-%m-%d')"
local -A tags_list=()
local tags_list_keys=()
local defaultIFS="$IFS"
local IFS="$defaultIFS"
# fetch our tags
local _ref _date _tag _tab='%x09'
while IFS=$'\t' read _ref _date _tag; do
[[ -z "${_tag}" ]] && continue
# strip out any additional tags pointing to same commit, remove tag label
_tag="${_tag%%,*}"; _tag="${_tag#tag: }"
# add tag to assoc array; copy tag to tag_list_keys for ordered iteration
tags_list["${_tag}"]="${_ref}=>${_date}"
tags_list_keys+=( "${_tag}" )
done <<< "$(git log --tags --simplify-by-decoration --date="short" --pretty="format:%h${_tab}%ad${_tab}%D")"
IFS="$defaultIFS"
unset _ref _date _tag _tab
local _tags_list_keys_length="${#tags_list_keys[@]}"
local _final_tag_found=false
local _start_tag_found=false
local i
for (( i=0; i<"${_tags_list_keys_length}"; i++ )); do
local __curr_tag="${tags_list_keys[$i]}"
local __prev_tag="${tags_list_keys[$i+1]:-null}"
local __curr_date="${tags_list[${__curr_tag}]##*=>}"
# output latest commits, up until the most-recent tag, these are all
# new commits made since the last tagged commit.
if [[ $i -eq 0 && ( -z "$final_tag" || "$final_tag" == "null" ) ]]; then
if [[ "$list_style" == true ]]; then
_formatCommitPlain "${__curr_tag}" >> "$tmpfile"
else
_formatCommitPretty "$title_tag" "$title_date" "${__curr_tag}"
fi
fi
# both final_tag and start_tag are "null", user just wanted recent commits
[[ "$final_tag" == "null" && "$start_tag" == "null" ]] && break;
# find the specified final tag, continue until found
if [[ -n "$final_tag" && "$final_tag" != "null" ]]; then
[[ "$final_tag" == "${__curr_tag}" ]] && _final_tag_found=true
[[ "$final_tag" != "${__curr_tag}" && "${_final_tag_found}" == false ]] && continue
fi
# find the specified start tag, break when found
if [[ -n "$start_tag" ]]; then
[[ "$start_tag" == "${__curr_tag}" ]] && _start_tag_found=true
[[ "$start_tag" != "${__curr_tag}" && "${_start_tag_found}" == true ]] && break
fi
# output commits made between prev_tag and curr_tag, these are all of the
# commits related to the tag of interest.
if [[ "$list_style" == true ]]; then
_formatCommitPlain "${__prev_tag}" "${__curr_tag}"
else
_formatCommitPretty "${__curr_tag}" "${__curr_date}" "${__prev_tag}" "${__curr_tag}"
fi
done
unset i
unset _start_tag_found
unset _final_tag_found
return
}
commitListPlain() {
local list_all="${1:-false}"
local start_tag="$2"
local final_tag="$3"
commitList "$list_all" "" "$start_tag" "$final_tag" "true"
}
commitListPretty() {
local list_all="${1:-false}"
local title_tag="$2"
local start_tag="$3"
local final_tag="$4"
local title_date="$(date +'%Y-%m-%d')"
commitList "$list_all" "$title_tag" "$start_tag" "$final_tag"
}
main() {
local start_tag="null" # empty string and "null" mean two different things!
local final_tag="null"
local -A option=()
option["list_all"]=false
option["list_style"]=false
option["title_tag"]="$DEF_TAG_RECENT"
option["start_tag"]=""
option["final_tag"]=""
option["output_file"]=""
option["use_stdout"]=false
option["prune_old"]=false
#
# We work chronologically backwards from NOW towards start_tag where NOW also
# includes the most-recent (un-tagged) commits. If no start_tag has been
# specified, we work back to the very first commit; if a final_tag has been
# specified, we begin at the final_tag and work backwards towards start_tag.
#
# An existing ChangeLog/History file will be appended to the output unless the
# prune old (-p | --prune-old) option has been enabled.
while [ "$1" != "" ]; do
case $1 in
-a | --all )
option["list_all"]=true
;;
-l | --list )
option["list_style"]=true
;;
-t | --tag )
option["title_tag"]="$2"
shift
;;
-f | --final-tag )
option["final_tag"]="$2"
shift
;;
-s | --start-tag )
option["start_tag"]="$2"
shift
;;
-n | --no-merges )
GIT_LOG_OPTS='--no-merges'
;;
-p | --prune-old )
option["prune_old"]=true
;;
-x | --stdout )
option["use_stdout"]=true
;;
-h | ? | help | --help )
_usage
exit 1
;;
* )
[[ "${1:0:1}" == '-' ]] && _error "Invalid option: $1" && _usage && exit 1
option["output_file"]="$1"
;;
esac
shift
done
if [[ -n "${option["start_tag"]}" ]]; then
start_tag="$(git describe --tags --abbrev=0 "${option["start_tag"]}" 2>/dev/null)"
if [[ -z "$start_tag" ]]; then
_error "Specified start-tag does not exist!"
return 1
fi
fi
fi
tmp=$(git_extra_mktemp)
printf "$HEAD" > $tmp
git-changelog $GIT_LOG_OPTS --list >> $tmp
printf '\n' >> $tmp
if [ -f $CHANGELOG ]; then cat $CHANGELOG >> $tmp; fi
mv -f $tmp $CHANGELOG
test -n "$EDITOR" && $EDITOR $CHANGELOG
if [[ -n "${option["final_tag"]}" ]]; then
final_tag="$(git describe --tags --abbrev=0 "${option["final_tag"]}" 2>/dev/null)"
if [[ -z "$final_tag" ]]; then
_error "Specified final-tag does not exist!"
return 1
fi
fi
#
# generate changelog
#
local tmpfile="$(git_extra_mktemp)"
local changelog="${option["output_file"]}"
local title_tag="${option["title_tag"]}"
if [[ "${option["list_style"]}" == true ]]; then
if [[ "${option["list_all"]}" == true ]]; then
commitListPlain "true" >> "$tmpfile"
else
commitListPlain "false" "$start_tag" "$final_tag" >> "$tmpfile"
fi
else
if [[ "${option["list_all"]}" == true ]]; then
commitListPretty "true" "$title_tag" >> "$tmpfile"
else
commitListPretty "false" "$title_tag" "$start_tag" "$final_tag" >> "$tmpfile"
fi
fi
if [[ -z "$changelog" ]]; then
changelog="$(ls | egrep 'change|history' -i | head -n1)"
if [[ -z "$changelog" ]]; then
changelog="History.md";
fi
fi
# append existing changelog?
if [[ -f "$changelog" && "${option["prune_old"]}" == false ]]; then
cat "$changelog" >> "$tmpfile"
fi
# output file to stdout or move into place
if [[ "${option["use_stdout"]}" == true ]]; then
cat "$tmpfile"
rm -f "$tmpfile"
else
mv -f "$tmpfile" "$changelog"
[[ -n "$GIT_EDITOR" ]] && $GIT_EDITOR "$changelog"
fi
return
}
main "$@"
exit 0

View file

@ -1,80 +1,135 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GIT\-CHANGELOG" "1" "November 2014" "" ""
.TH "GIT\-CHANGELOG" "1" "March 2015" "" "Git Extras"
.
.SH "NAME"
\fBgit\-changelog\fR \- Generate the changelog report
\fBgit\-changelog\fR \- Generate a changelog report
.
.SH "SYNOPSIS"
\fBgit\-changelog\fR [\-l, \-\-list]
\fBgit\-changelog\fR [options] [<file>]
.
.br
\fBgit\-changelog\fR {\-h | \-\-help | ?}
.
.SH "DESCRIPTION"
Populates the file named matching \fIchange|history \-i\fR with the commits since the previous tag or since the project began when no tags are present\. Opens the changelog in \fB$EDITOR\fR when set\.
Generates a changelog from git(1) tags (annotated or lightweight) and commit messages\. Existing changelog files with filenames that begin with \fIChange\fR or \fIHistory\fR will be identified automatically with a case insensitive match pattern and existing content will be appended to the new output generated\-\-this behavior can be disabled by specifying the prune option (\-p|\-\-prune\-old)\. The generated file will be opened in \fB$EDITOR\fR when set\.
.
.P
If no tags exist, then all commits are output; if tags exist, then only the most\-recent commits are output up to the last identified tag\. This behavior can be changed by specifing one or both of the range options (\-f|\-\-final\-tag and \-s|\-\-start\-tag)\.
.
.SH "OPTIONS"
<file>
.
.P
The name of the output file\. By default the new file will be \fIHistory\.md\fR unless an existing changelog is detected in which case the existing file will be updated\.
.
.P
\-a, \-\-all
.
.P
Retrieve all commits\. Ignores \-s|\-\-start\-tag and \-f|\-\-final\-tag options (if set)\.
.
.P
\-l, \-\-list
.
.P
Show commit logs from the current version\.
Show commits in list format (without titles, dates)\.
.
.P
\-\-no\-merges
\-t, \-\-tag
.
.P
Specify a tag label to use for most\-recent (untagged) commits\.
.
.P
\-f, \-\-final\-tag
.
.P
When specifying a range, the newest tag at which point commit retrieval will end\. Commits will be returned from the very first commit until the final tag unless a start tag is also specified\.
.
.P
\-s, \-\-start\-tag
.
.P
When specifying a range, the oldest tag to retrieve commits from\. Commits will be returned from the start tag to now unless a final tag is also specified\.
.
.P
\-n, \-\-no\-merges
.
.P
Filters out merge commits (commits with more than 1 parent) from generated changelog\.
.
.P
\-p, \-\-prune\-old
.
.P
Replace existing changelog entirely with newly generated content, thereby disabling the default behavior of appending the content of any detected changelog to the end of newly generated content\.
.
.P
\-x, \-\-stdout
.
.P
Write output to stdout instead of to a new changelog file\.
.
.P
\-h, \-\-help, ?
.
.P
Show a help message with basic usage information\.
.
.SH "EXAMPLES"
.
.IP "\(bu" 4
Updating changelog file:
.TP
Updating existing file or creating a new \fIHistory\.md\fR file with pretty formatted output:
.
.IP
$ git changelog
.
.IP "\(bu" 4
.TP
Listing commits from the current version:
.
.IP
$ git changelog \-\-list
.
.IP "\(bu" 4
Docs for git\-ignore\. Closes #3
.TP
Listing a range of commits from 2\.1\.0 to now:
.
.IP "\(bu" 4
Merge branch \'ignore\'
.IP
$ git changelog \-\-list \-\-start\-tag 2\.1\.0
.
.IP "\(bu" 4
Added git\-ignore
.TP
Listing a pretty formatted version of the same:
.
.IP "\(bu" 4
Fixed <tag> in docs
.IP
$ git changelog \-\-start\-tag 2\.1\.0
.
.IP "\(bu" 4
Install docs
.TP
Listing a range of commits from initial commit to 2\.1\.0:
.
.IP "\(bu" 4
Merge branch \'release\'
.IP
$ git changelog \-\-list \-\-final\-tag 2\.1\.0
.
.IP "\(bu" 4
Added git\-release
.TP
Listing a pretty formatted range of commits between 0\.5\.0 and 1\.0\.0:
.
.IP "\(bu" 4
Passing args to git shortlog
.IP
$ git changelog \-\-start\-tag 0\.5\.0 \-\-final\-tag 1\.0\.0
.
.IP "\(bu" 4
Added \-\-all support to git\-count
.TP
Specifying a file for output:
.
.IP "\(bu" 4
Initial commit
.IP
$ git changelog ChangeLog\.md
.
.IP "" 0
.TP
And if an existing Changelog exists, replace its contents entirely:
.
.IP "" 0
.IP
$ git changelog \-\-prune\-old
.
.SH "AUTHOR"
Written by Tj Holowaychuk <\fItj@vision\-media\.ca\fR>
Written by Mark Eissler <\fImark@mixtur\.com\fR>
.
.SH "REPORTING BUGS"
<\fIhttps://github\.com/tj/git\-extras/issues\fR>

View file

@ -3,7 +3,7 @@
<head>
<meta http-equiv='content-type' value='text/html;charset=utf8'>
<meta name='generator' value='Ronn/v0.7.3 (http://github.com/rtomayko/ronn/tree/0.7.3)'>
<title>git-changelog(1) - Generate the changelog report</title>
<title>git-changelog(1) - Generate a changelog report</title>
<style type='text/css' media='all'>
/* style: man */
body#manpage {margin:0}
@ -65,62 +65,101 @@
<ol class='man-decor man-head man head'>
<li class='tl'>git-changelog(1)</li>
<li class='tc'></li>
<li class='tc'>Git Extras</li>
<li class='tr'>git-changelog(1)</li>
</ol>
<h2 id="NAME">NAME</h2>
<p class="man-name">
<code>git-changelog</code> - <span class="man-whatis">Generate the changelog report</span>
<code>git-changelog</code> - <span class="man-whatis">Generate a changelog report</span>
</p>
<h2 id="SYNOPSIS">SYNOPSIS</h2>
<p><code>git-changelog</code> [-l, --list]</p>
<p><code>git-changelog</code> [options] [&lt;file&gt;]<br />
<code>git-changelog</code> {-h | --help | ?}</p>
<h2 id="DESCRIPTION">DESCRIPTION</h2>
<p> Populates the file named matching <em>change|history -i</em> with the commits since the previous tag or since the project began when no tags are present. Opens the changelog in <strong>$EDITOR</strong> when set.</p>
<p> Generates a changelog from <span class="man-ref">git<span class="s">(1)</span></span> tags (annotated or lightweight) and commit messages. Existing changelog files with filenames that begin with <em>Change</em> or <em>History</em> will be identified automatically with a case insensitive match pattern and existing content will be appended to the new output generated--this behavior can be disabled by specifying the prune option (-p|--prune-old). The generated file will be opened in <strong>$EDITOR</strong> when set.</p>
<p> If no tags exist, then all commits are output; if tags exist, then only the most-recent commits are output up to the last identified tag. This behavior can be changed by specifing one or both of the range options (-f|--final-tag and -s|--start-tag).</p>
<h2 id="OPTIONS">OPTIONS</h2>
<p> &lt;file&gt;</p>
<p> The name of the output file. By default the new file will be <em>History.md</em> unless an existing changelog is detected in which case the existing file will be updated.</p>
<p> -a, --all</p>
<p> Retrieve all commits. Ignores -s|--start-tag and -f|--final-tag options (if set).</p>
<p> -l, --list</p>
<p> Show commit logs from the current version.</p>
<p> Show commits in list format (without titles, dates).</p>
<p> --no-merges</p>
<p> -t, --tag</p>
<p> Specify a tag label to use for most-recent (untagged) commits.</p>
<p> -f, --final-tag</p>
<p> When specifying a range, the newest tag at which point commit retrieval will end. Commits will be returned from the very first commit until the final tag unless a start tag is also specified.</p>
<p> -s, --start-tag</p>
<p> When specifying a range, the oldest tag to retrieve commits from. Commits will be returned from the start tag to now unless a final tag is also specified.</p>
<p> -n, --no-merges</p>
<p> Filters out merge commits (commits with more than 1 parent) from generated changelog.</p>
<p> -p, --prune-old</p>
<p> Replace existing changelog entirely with newly generated content, thereby disabling the default behavior of appending the content of any detected changelog to the end of newly generated content.</p>
<p> -x, --stdout</p>
<p> Write output to stdout instead of to a new changelog file.</p>
<p> -h, --help, ?</p>
<p> Show a help message with basic usage information.</p>
<h2 id="EXAMPLES">EXAMPLES</h2>
<ul>
<li><p>Updating changelog file:</p>
<dl>
<dt>Updating existing file or creating a new <em>History.md</em> file with pretty formatted output:</dt><dd><p></p>
<p>$ git changelog</p></li>
<li><p>Listing commits from the current version:</p>
<p>$ git changelog</p></dd>
<dt>Listing commits from the current version:</dt><dd><p></p>
<p>$ git changelog --list</p>
<p>$ git changelog --list</p></dd>
<dt>Listing a range of commits from 2.1.0 to now:</dt><dd><p></p>
<ul>
<li>Docs for git-ignore. Closes #3</li>
<li>Merge branch 'ignore'</li>
<li>Added git-ignore</li>
<li>Fixed &lt;tag&gt; in docs</li>
<li>Install docs</li>
<li>Merge branch 'release'</li>
<li>Added git-release</li>
<li>Passing args to git shortlog</li>
<li>Added --all support to git-count</li>
<li>Initial commit</li>
</ul>
</li>
</ul>
<p>$ git changelog --list --start-tag 2.1.0</p></dd>
<dt>Listing a pretty formatted version of the same:</dt><dd><p></p>
<p>$ git changelog --start-tag 2.1.0</p></dd>
<dt>Listing a range of commits from initial commit to 2.1.0:</dt><dd><p></p>
<p>$ git changelog --list --final-tag 2.1.0</p></dd>
<dt>Listing a pretty formatted range of commits between 0.5.0 and 1.0.0:</dt><dd><p></p>
<p>$ git changelog --start-tag 0.5.0 --final-tag 1.0.0</p></dd>
<dt>Specifying a file for output:</dt><dd><p></p>
<p>$ git changelog ChangeLog.md</p></dd>
<dt>And if an existing Changelog exists, replace its contents entirely:</dt><dd><p></p>
<p>$ git changelog --prune-old</p></dd>
</dl>
<h2 id="AUTHOR">AUTHOR</h2>
<p>Written by Tj Holowaychuk &lt;<a href="&#x6d;&#x61;&#105;&#x6c;&#116;&#111;&#58;&#x74;&#106;&#x40;&#118;&#x69;&#x73;&#105;&#111;&#110;&#45;&#x6d;&#101;&#100;&#x69;&#97;&#x2e;&#99;&#x61;" data-bare-link="true">&#x74;&#x6a;&#64;&#x76;&#105;&#115;&#105;&#x6f;&#110;&#x2d;&#109;&#101;&#100;&#x69;&#97;&#x2e;&#99;&#97;</a>&gt;</p>
<p>Written by Mark Eissler &lt;<a href="&#109;&#97;&#x69;&#x6c;&#x74;&#x6f;&#58;&#x6d;&#x61;&#x72;&#x6b;&#64;&#x6d;&#x69;&#120;&#x74;&#x75;&#114;&#x2e;&#99;&#111;&#109;" data-bare-link="true">&#109;&#x61;&#x72;&#107;&#64;&#109;&#x69;&#x78;&#116;&#117;&#x72;&#x2e;&#x63;&#111;&#109;</a>&gt;</p>
<h2 id="REPORTING-BUGS">REPORTING BUGS</h2>
@ -133,7 +172,7 @@
<ol class='man-decor man-foot man foot'>
<li class='tl'></li>
<li class='tc'>November 2014</li>
<li class='tc'>March 2015</li>
<li class='tr'>git-changelog(1)</li>
</ol>

View file

@ -1,27 +1,62 @@
git-changelog(1) -- Generate the changelog report
=================================================
git-changelog(1) -- Generate a changelog report
===============================================
## SYNOPSIS
`git-changelog` [-l, --list]
`git-changelog` [options] [&lt;file&gt;]<br>
`git-changelog` {-h | --help | ?}
## DESCRIPTION
Populates the file named matching _change|history -i_ with the commits since the previous tag or since the project began when no tags are present. Opens the changelog in **$EDITOR** when set.
Generates a changelog from git(1) tags (annotated or lightweight) and commit messages. Existing changelog files with filenames that begin with _Change_ or _History_ will be identified automatically with a case insensitive match pattern and existing content will be appended to the new output generated--this behavior can be disabled by specifying the prune option (-p|--prune-old). The generated file will be opened in **$EDITOR** when set.
If no tags exist, then all commits are output; if tags exist, then only the most-recent commits are output up to the last identified tag. This behavior can be changed by specifing one or both of the range options (-f|--final-tag and -s|--start-tag).
## OPTIONS
&lt;file&gt;
The name of the output file. By default the new file will be _History.md_ unless an existing changelog is detected in which case the existing file will be updated.
-a, --all
Retrieve all commits. Ignores -s|--start-tag and -f|--final-tag options (if set).
-l, --list
Show commit logs from the current version.
Show commits in list format (without titles, dates).
--no-merges
-t, --tag
Specify a tag label to use for most-recent (untagged) commits.
-f, --final-tag
When specifying a range, the newest tag at which point commit retrieval will end. Commits will be returned from the very first commit until the final tag unless a start tag is also specified.
-s, --start-tag
When specifying a range, the oldest tag to retrieve commits from. Commits will be returned from the start tag to now unless a final tag is also specified.
-n, --no-merges
Filters out merge commits (commits with more than 1 parent) from generated changelog.
-p, --prune-old
Replace existing changelog entirely with newly generated content, thereby disabling the default behavior of appending the content of any detected changelog to the end of newly generated content.
-x, --stdout
Write output to stdout instead of to a new changelog file.
-h, --help, ?
Show a help message with basic usage information.
## EXAMPLES
* Updating changelog file:
* Updating existing file or creating a new _History.md_ file with pretty formatted output:
$ git changelog
@ -29,20 +64,33 @@ git-changelog(1) -- Generate the changelog report
$ git changelog --list
* Docs for git-ignore. Closes #3
* Merge branch 'ignore'
* Added git-ignore
* Fixed &lt;tag&gt; in docs
* Install docs
* Merge branch 'release'
* Added git-release
* Passing args to git shortlog
* Added --all support to git-count
* Initial commit
* Listing a range of commits from 2.1.0 to now:
$ git changelog --list --start-tag 2.1.0
* Listing a pretty formatted version of the same:
$ git changelog --start-tag 2.1.0
* Listing a range of commits from initial commit to 2.1.0:
$ git changelog --list --final-tag 2.1.0
* Listing a pretty formatted range of commits between 0.5.0 and 1.0.0:
$ git changelog --start-tag 0.5.0 --final-tag 1.0.0
* Specifying a file for output:
$ git changelog ChangeLog.md
* And if an existing Changelog exists, replace its contents entirely:
$ git changelog --prune-old
## AUTHOR
Written by Tj Holowaychuk &lt;<tj@vision-media.ca>&gt;
Written by Mark Eissler &lt;<mark@mixtur.com>&gt;
## REPORTING BUGS