git-changelog: add --start-commit option, like --start-tag but for commit

This commit is contained in:
spacewander 2018-06-16 12:19:11 +08:00
parent 4e1cd73e59
commit 792b697450
5 changed files with 109 additions and 14 deletions

View file

@ -22,11 +22,12 @@ 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)
-a, --all Retrieve all commits (ignores --start-tag/commit, --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
--start-commit Like --start-tag but use commit instead of tag
-n, --no-merges Suppress commits from merged branches
-m, --merges-only Only uses merge commits (uses both subject and body of commit)
-p, --prune-old Replace existing Changelog entirely with new content
@ -187,7 +188,8 @@ commitList() {
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 list_style="${1:-false}"; shift # enable/disable list format
local start_commit="$1"; shift
local changelog="$FILE"
local title_date="$(date +'%Y-%m-%d')"
local tags_list=()
@ -195,6 +197,19 @@ commitList() {
local defaultIFS="$IFS"
local IFS="$defaultIFS"
if [[ -n "$start_commit" && "$final_tag" == "null" \
&& "$start_tag" == "null" ]]; then
# if there is not tag after $start_commit,
# output directly without fetch all tags
if [[ "$list_style" == true ]]; then
_formatCommitPlain "${start_commit}~"
else
_formatCommitPretty "$title_tag" "$title_date" "$start_commit~"
fi
return
fi
#
# Tags look like this:
#
@ -290,7 +305,23 @@ commitList() {
# 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
if [[ "${_start_tag_found}" == true ]]; then
if [[ -n "$start_commit" ]]; then
# output commits after start_commit to its closest tag
if [[ "$list_style" == true ]]; then
_formatCommitPlain "$start_commit~" "${__curr_tag}"
else
_formatCommitPretty "${__curr_tag}" "${__curr_date}" \
"$start_commit~" "${__curr_tag}"
fi
break
fi
[[ "$start_tag" != "${__curr_tag}" ]] && break
fi
fi
# output commits made between prev_tag and curr_tag, these are all of the
@ -316,8 +347,9 @@ commitListPlain() {
local list_all="${1:-false}"
local start_tag="$2"
local final_tag="$3"
local start_commit="$4"
commitList "$list_all" "" "$start_tag" "$final_tag" "true"
commitList "$list_all" "" "$start_tag" "$final_tag" "true" "$start_commit"
}
commitListPretty() {
@ -325,9 +357,11 @@ commitListPretty() {
local title_tag="$2"
local start_tag="$3"
local final_tag="$4"
local start_commit="$5"
local title_date="$(date +'%Y-%m-%d')"
commitList "$list_all" "$title_tag" "$start_tag" "$final_tag"
commitList "$list_all" "$title_tag" "$start_tag" "$final_tag" "false" \
"$start_commit"
}
_exit() {
@ -374,6 +408,7 @@ main() {
"list_style:false"
"title_tag:$DEF_TAG_RECENT"
"start_tag:"
"start_commit:"
"final_tag:"
"output_file:"
"use_stdout:false"
@ -410,6 +445,10 @@ main() {
option=( $(_setValueForKeyFakeAssocArray "start_tag" "$2" "${option[*]}") )
shift
;;
--start-commit )
option=( $(_setValueForKeyFakeAssocArray "start_commit" "$2" "${option[*]}") )
shift
;;
-n | --no-merges )
GIT_LOG_OPTS='--no-merges'
CUR_GIT_LOG_FORMAT="$GIT_LOG_FORMAT"
@ -440,13 +479,39 @@ main() {
[[ -z "$CUR_GIT_LOG_FORMAT" ]] && CUR_GIT_LOG_FORMAT="$GIT_LOG_FORMAT"
local _tag="$(_valueForKeyFakeAssocArray "start_tag" "${option[*]}")"
if [[ -n "${_tag}" ]]; then
local start_commit="$(_valueForKeyFakeAssocArray "start_commit" "${option[*]}")"
if [[ -n "$start_commit" ]]; then
if [[ -n "${_tag}" ]]; then
_error "--start-tag could not use with --start-commit!"
return 1
fi
start_commit="$start_commit"
start_tag="$(git describe --tags --contains "$start_commit" 2>/dev/null || echo 'null')"
if [[ -z "$start_tag" ]]; then
_error "Could find the associative tag for the start-commit!"
return 1
fi
# remove suffix from the $start_tag when no tag matched exactly
start_tag="${start_tag%%~*}"
elif [[ -n "${_tag}" ]]; then
start_tag="$(git describe --tags --abbrev=0 "${_tag}" 2>/dev/null)"
if [[ -z "$start_tag" ]]; then
_error "Specified start-tag does not exist!"
return 1
fi
fi
if [[ -n "${_tag}" ]]; then
if [[ -n "$start_commit" ]]; then
_error "--start-tag could not use with --start-commit!"
return 1
fi
fi
unset _tag
local _tag="$(_valueForKeyFakeAssocArray "final_tag" "${option[*]}")"
@ -470,13 +535,15 @@ main() {
if [[ "$(_valueForKeyFakeAssocArray "list_all" "${option[*]}")" == true ]]; then
commitListPlain "true" >> "$tmpfile"
else
commitListPlain "false" "$start_tag" "$final_tag" >> "$tmpfile"
commitListPlain "false" "$start_tag" "$final_tag" \
"$start_commit" >> "$tmpfile"
fi
else
if [[ "$(_valueForKeyFakeAssocArray "list_all" "${option[*]}")" == true ]]; then
commitListPretty "true" "$title_tag" >> "$tmpfile"
else
commitListPretty "false" "$title_tag" "$start_tag" "$final_tag" >> "$tmpfile"
commitListPretty "false" "$title_tag" "$start_tag" "$final_tag" \
"$start_commit" >> "$tmpfile"
fi
fi

View file

@ -12,6 +12,7 @@ _git_changelog(){
'--tag'
'--final-tag'
'--start-tag'
'--start-commit'
'--no-merges'
'--prune-old'
'--stdout'

View file

@ -1,7 +1,7 @@
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "GIT\-CHANGELOG" "1" "January 2018" "" "Git Extras"
.TH "GIT\-CHANGELOG" "1" "June 2018" "" "Git Extras"
.
.SH "NAME"
\fBgit\-changelog\fR \- Generate a changelog report
@ -39,7 +39,7 @@ The name of the output file\. By default the new file will be \fIHistory\.md\fR
\-a, \-\-all
.
.P
Retrieve all commits\. Ignores \-s|\-\-start\-tag and \-f|\-\-final\-tag options (if set)\.
Retrieve all commits\. Ignores \-s|\-\-start\-tag/commit and \-f|\-\-final\-tag options (if set)\.
.
.P
\-l, \-\-list
@ -66,6 +66,12 @@ When specifying a range, the newest tag at which point commit retrieval will end
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
\-\-start\-commit
.
.P
Like the \-\-start\-tag but specify the oldest commit instead of tag\. Note that the specified commit will be contained in the changelog\.
.
.P
\-n, \-\-no\-merges
.
.P
@ -134,6 +140,12 @@ 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
.
.TP
Listing a pretty formatted range of commits between 0b97430 and 1\.0\.0:
.
.IP
$ git changelog \-\-start\-commit 0b97430 \-\-final\-tag 1\.0\.0
.
.TP
Specifying a file for output:
.
.IP

View file

@ -101,7 +101,7 @@
<p> -a, --all</p>
<p> Retrieve all commits. Ignores -s|--start-tag and -f|--final-tag options (if set).</p>
<p> Retrieve all commits. Ignores -s|--start-tag/commit and -f|--final-tag options (if set).</p>
<p> -l, --list</p>
@ -119,6 +119,10 @@
<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> --start-commit</p>
<p> Like the --start-tag but specify the oldest commit instead of tag. Note that the specified commit will be contained in the changelog.</p>
<p> -n, --no-merges</p>
<p> Filters out merge commits (commits with more than 1 parent) from generated changelog.</p>
@ -160,6 +164,9 @@
<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>Listing a pretty formatted range of commits between 0b97430 and 1.0.0:</dt><dd><p></p>
<p>$ git changelog --start-commit 0b97430 --final-tag 1.0.0</p></dd>
<dt>Specifying a file for output:</dt><dd><p></p>
<p>$ git changelog ChangeLog.md</p></dd>
@ -171,7 +178,7 @@
<h2 id="AUTHOR">AUTHOR</h2>
<p>Written by Mark Eissler &lt;<a href="&#109;&#x61;&#x69;&#x6c;&#116;&#x6f;&#58;&#x6d;&#97;&#114;&#107;&#64;&#x6d;&#x69;&#120;&#x74;&#x75;&#114;&#x2e;&#x63;&#111;&#x6d;" data-bare-link="true">&#x6d;&#x61;&#x72;&#x6b;&#64;&#109;&#x69;&#x78;&#x74;&#x75;&#114;&#46;&#99;&#111;&#109;</a>&gt;</p>
<p>Written by Mark Eissler &lt;<a href="&#x6d;&#97;&#x69;&#x6c;&#x74;&#x6f;&#58;&#x6d;&#x61;&#x72;&#x6b;&#x40;&#x6d;&#105;&#120;&#116;&#117;&#x72;&#46;&#99;&#x6f;&#x6d;" data-bare-link="true">&#109;&#x61;&#114;&#107;&#x40;&#109;&#x69;&#x78;&#116;&#117;&#x72;&#46;&#x63;&#111;&#x6d;</a>&gt;</p>
<h2 id="REPORTING-BUGS">REPORTING BUGS</h2>
@ -184,7 +191,7 @@
<ol class='man-decor man-foot man foot'>
<li class='tl'></li>
<li class='tc'>January 2018</li>
<li class='tc'>June 2018</li>
<li class='tr'>git-changelog(1)</li>
</ol>

View file

@ -26,7 +26,7 @@ git-changelog(1) -- Generate a changelog report
-a, --all
Retrieve all commits. Ignores -s|--start-tag and -f|--final-tag options (if set).
Retrieve all commits. Ignores -s|--start-tag/commit and -f|--final-tag options (if set).
-l, --list
@ -44,6 +44,10 @@ git-changelog(1) -- Generate a changelog report
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.
--start-commit
Like the --start-tag but specify the oldest commit instead of tag. Note that the specified commit will be contained in the changelog.
-n, --no-merges
Filters out merge commits (commits with more than 1 parent) from generated changelog.
@ -90,6 +94,10 @@ git-changelog(1) -- Generate a changelog report
$ git changelog --start-tag 0.5.0 --final-tag 1.0.0
* Listing a pretty formatted range of commits between 0b97430 and 1.0.0:
$ git changelog --start-commit 0b97430 --final-tag 1.0.0
* Specifying a file for output:
$ git changelog ChangeLog.md