diff options
| author | Marc Cornellà <hello@mcornella.com> | 2021-10-26 18:24:29 +0200 | 
|---|---|---|
| committer | Marc Cornellà <hello@mcornella.com> | 2021-10-26 21:04:00 +0200 | 
| commit | 9c8131e417a15fccb15615e3b03ce44a53678fe0 (patch) | |
| tree | 18ff0e6bd7d07732bae19f246c455d708c441f14 /tools | |
| parent | 4f67b02a9f43b0996ad85ee600b468399e1477e5 (diff) | |
| download | zsh-9c8131e417a15fccb15615e3b03ce44a53678fe0.tar.gz zsh-9c8131e417a15fccb15615e3b03ce44a53678fe0.tar.bz2 zsh-9c8131e417a15fccb15615e3b03ce44a53678fe0.zip | |
perf(changelog): use a single `git log` command to get all commit messages
Diffstat (limited to 'tools')
| -rwxr-xr-x | tools/changelog.sh | 50 | 
1 files changed, 34 insertions, 16 deletions
| diff --git a/tools/changelog.sh b/tools/changelog.sh index ebdffba0a..13cfb9530 100755 --- a/tools/changelog.sh +++ b/tools/changelog.sh @@ -1,5 +1,8 @@  #!/usr/bin/env zsh +cd "$ZSH" +setopt extendedglob +  ##############################  # CHANGELOG SCRIPT CONSTANTS #  ############################## @@ -114,15 +117,8 @@ function parse-commit {      fi    } -  # Ignore commit if it is a merge commit -  if [[ $(command git show -s --format=%p $1 | wc -w) -gt 1 ]]; then -    return -  fi -    # Parse commit with hash $1 -  local hash="$1" subject body warning rhash -  subject="$(command git show -s --format=%s $hash)" -  body="$(command git show -s --format=%b $hash)" +  local hash="$1" subject="$2" body="$3" warning rhash    # Commits following Conventional Commits (https://www.conventionalcommits.org/)    # have the following format, where parts between [] are optional: @@ -384,7 +380,8 @@ function main {    # Commit classification arrays    local -A commits subjects scopes breaking reverts    local truncate=0 read_commits=0 -  local hash version tag +  local version tag +  local hash refs subject body    # Get the first version name:    # 1) try tag-like version, or @@ -396,17 +393,40 @@ function main {      || version=$(command git symbolic-ref --quiet --short $until 2>/dev/null) \      || version=$(command git rev-parse --short $until 2>/dev/null) -  # Get commit list from $until commit until $since commit, or until root -  # commit if $since is unset, in short hash form. -  command git rev-list --abbrev-commit --abbrev=7 ${since:+$since..}$until | while read hash; do +  # Get commit list from $until commit until $since commit, or until root commit if $since is unset +  local range=${since:+$since..}$until + +  # Git log options +  # -z:             commits are delimited by null bytes +  # --format:       [7-char hash]<field sep>[ref names]<field sep>[subject]<field sep>[body] +  # --abbrev=7:     force commit hashes to be 7 characters long +  # --no-merges:    merge commits are omitted +  local SEP="0mZmAgIcSeP" +  local -a raw_commits +  raw_commits=(${(0)"$(command git log -z \ +    --format="%h${SEP}%D${SEP}%s${SEP}%b" --abbrev=7 \ +    --no-merges $range)"}) + +  local raw_commit +  local -a raw_fields +  for raw_commit in $raw_commits; do      # Truncate list on versions with a lot of commits      if (( ++read_commits > 40 )); then        truncate=1        break      fi +    # Read the commit fields (@ is needed to keep empty values) +    raw_fields=("${(@ps:$SEP:)raw_commit}") +    hash="${raw_fields[1]}" +    refs="${raw_fields[2]}" +    subject="${raw_fields[3]}" +    body="${raw_fields[4]}" +      # If we find a new release (exact tag) -    if tag=$(command git describe --exact-match --tags $hash 2>/dev/null); then +    if [[ "$refs" = *tag:\ * ]]; then +      # Parse tag name (needs: setopt extendedglob) +      tag="${${refs##*tag: }%%,# *}"        # Output previous release        display-release        # Reinitialize commit storage @@ -420,7 +440,7 @@ function main {        read_commits=1      fi -    parse-commit "$hash" +    parse-commit "$hash" "$subject" "$body"    done    display-release @@ -431,8 +451,6 @@ function main {    fi  } -cd "$ZSH" -  # Use raw output if stdout is not a tty  if [[ ! -t 1 && -z "$3" ]]; then    main "$1" "$2" --raw | 
