diff --git a/bin/git-changelog b/bin/git-changelog index b5eeae9a7..6a398654b 100755 --- a/bin/git-changelog +++ b/bin/git-changelog @@ -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 diff --git a/etc/bash_completion.sh b/etc/bash_completion.sh index d720ab43d..de2bd2ef5 100644 --- a/etc/bash_completion.sh +++ b/etc/bash_completion.sh @@ -12,6 +12,7 @@ _git_changelog(){ '--tag' '--final-tag' '--start-tag' + '--start-commit' '--no-merges' '--prune-old' '--stdout' diff --git a/man/git-changelog.1 b/man/git-changelog.1 index 88397bc18..e28b870a0 100644 --- a/man/git-changelog.1 +++ b/man/git-changelog.1 @@ -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 diff --git a/man/git-changelog.html b/man/git-changelog.html index e2c8cba10..0b979a965 100644 --- a/man/git-changelog.html +++ b/man/git-changelog.html @@ -101,7 +101,7 @@

OPTIONS

-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

@@ -119,6 +119,10 @@

OPTIONS

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.

@@ -160,6 +164,9 @@

EXAMPLES

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

+
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

@@ -171,7 +178,7 @@

EXAMPLES

AUTHOR

-

Written by Mark Eissler <mark@mixtur.com>

+

Written by Mark Eissler <mark@mixtur.com>

REPORTING BUGS

@@ -184,7 +191,7 @@

SEE ALSO

  1. -
  2. January 2018
  3. +
  4. June 2018
  5. git-changelog(1)
diff --git a/man/git-changelog.md b/man/git-changelog.md index 4e8424366..d0060698a 100644 --- a/man/git-changelog.md +++ b/man/git-changelog.md @@ -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