Remove git notes usage from release process

Previously we store release name, candidate number, cherry-picks and
release notes info in git repo using `git notes`.  To remove this
complexity, we remove all git notes usage in this change.

Instead of using git notes, we parse release name and candidate number
from branch name or tag name.  For cherry-picks, we rely on the git
patch-id to find the original commit hash. And for release notes, there
is no need to store it in git notes, because we always manually modify
the generated release note.

Closes #10741.

PiperOrigin-RevId: 294639345
diff --git a/scripts/ci/build.sh b/scripts/ci/build.sh
index a4d3b19..6d9fec9 100755
--- a/scripts/ci/build.sh
+++ b/scripts/ci/build.sh
@@ -24,8 +24,9 @@
 #     Also prepare an email for announcing the release.
 
 # Load common.sh
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-source "$(dirname ${SCRIPT_DIR})/release/common.sh"
+BUILD_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+source "$(dirname ${BUILD_SCRIPT_DIR})/release/common.sh"
+source "$(dirname ${BUILD_SCRIPT_DIR})/release/relnotes.sh"
 
 if ! command -v gsutil &>/dev/null; then
   echo "Required tool 'gsutil' not found. Please install it:"
@@ -100,14 +101,14 @@
         "%url%" "$(generate_from_template "${RELEASE_CANDIDATE_URL}" "${args[@]}")"
     )
     generate_from_template \
-        "$(cat "${SCRIPT_DIR}/rc_email.txt")" \
+        "$(cat "${BUILD_SCRIPT_DIR}/rc_email.txt")" \
         "${args[@]}"
   elif [ -n "${release_name}" ]; then
     args+=(
         "%url%" "$(generate_from_template "${RELEASE_URL}" "${args[@]}")"
     )
     generate_from_template \
-        "$(cat "${SCRIPT_DIR}/release_email.txt")" "${args[@]}"
+        "$(cat "${BUILD_SCRIPT_DIR}/release_email.txt")" "${args[@]}"
   fi
 }
 
diff --git a/scripts/release/common.sh b/scripts/release/common.sh
index 3df3e32..240171f 100755
--- a/scripts/release/common.sh
+++ b/scripts/release/common.sh
@@ -44,19 +44,27 @@
   git symbolic-ref --short HEAD
 }
 
+# Returns the tag name of the current git repository
+function git_get_tag() {
+  git describe --tag
+}
+
 # Show the commit message of the ref specified in argument
 function git_commit_msg() {
   git show -s --pretty=format:%B "$@"
 }
 
-# Extract the release candidate number from the git notes
+# Extract the release candidate number from the git branch name
 function get_release_candidate() {
-  git notes --ref=release-candidate show "$@" 2>/dev/null || true
+  # Match rcX and return X
+  git_get_branch 2>/dev/null | grep -Po "(?<=rc)([0-9]|\.)*$" || true
 }
 
-# Extract the release name from the git notes
+# Extract the release name from the git branch name
 function get_release_name() {
-  git notes --ref=release show "$@" 2>/dev/null || true
+  # Match branch name release-X.X.X-rcY and return X.X.X
+  # or match tag name X.X.X and return X.X.X
+  git_get_branch 2>/dev/null | grep -Po "(?<=release-)([0-9]|\.)*(?=rc)" || git_get_tag | grep -Po "^([0-9]|\.)*$" || true
 }
 
 # Get the list of commit hashes between two revisions
@@ -67,7 +75,7 @@
   git log --pretty=format:%H "${baseline}".."${head}" "$@"
 }
 
-# Extract the full release name from the git notes
+# Extract the full release name from the branch name or tag name
 function get_full_release_name() {
   local name="$(get_release_name "$@")"
   local rc="$(get_release_candidate "$@")"
@@ -78,11 +86,6 @@
   fi
 }
 
-# Extract the release notes from the git notes
-function get_release_notes() {
-  git notes --ref=release-notes show "$@" 2>/dev/null || true
-}
-
 # Returns the info from the branch of the release. It is the current branch
 # but it errors out if the current branch is not a release branch. This
 # method returns the tag of the release and the number of the current
@@ -101,115 +104,3 @@
   fold -s -w $1 | sed 's/ *$//'
 }
 
-# Create the revision information given a list of commits. The first
-# commit should be the baseline, and the other ones are the cherry-picks.
-# The result is of the form:
-# Baseline: BASELINE_COMMIT
-#
-# Cherry picks:
-#
-#    + CHERRY_PICK1: commit message summary of the CHERRY_PICK1. This
-#                    message will be wrapped into 70 columns.
-#    + CHERRY_PICK2: commit message summary of the CHERRY_PICK2.
-function __create_revision_information() {
-  echo "Baseline: $(__git_commit_hash "${1}")"
-  local first=1
-  shift
-  while [ -n "${1-}" ]; do
-    if [[ "$first" -eq 1 ]]; then
-      echo -e "\nCherry picks:"
-      echo
-      first=0
-    fi
-    local hash="$(__git_commit_hash "${1}")"
-    local subject="$(__git_commit_subject $hash)"
-    local lines=$(echo "$subject" | wrap_text 65)  # 5 leading spaces.
-    echo "   + $hash:"
-    echo "$lines" | sed 's/^/     /'
-    shift
-  done
-}
-
-# Get the baseline of master.
-# Args: $1: release branch (or HEAD)
-# TODO(philwo) this gives the wrong baseline when HEAD == release == master.
-function get_release_baseline() {
-  git merge-base master "$1"
-}
-
-# Get the list of cherry-picks since master
-# Args:
-#   $1: branch, default to HEAD
-#   $2: baseline change, default to $(get_release_baseline $1)
-function get_cherrypicks() {
-  local branch="${1:-HEAD}"
-  local baseline="${2:-$(get_release_baseline "${branch}")}"
-  # List of changes since the baseline on the release branch
-  local changes="$(git_log_hash "${baseline}" "${branch}" --reverse)"
-  # List of changes since the baseline on the master branch, and their patch-id
-  local master_changes="$(git_log_hash "${baseline}" master | xargs git show | git patch-id)"
-  # Now for each changes on the release branch
-  for i in ${changes}; do
-    local hash=$(git notes --ref=cherrypick show "$i" 2>/dev/null || true)
-    if [ -z "${hash}" ]; then
-      # Find the change with the same patch-id on the master branch if the note is not present
-      hash=$(echo "${master_changes}" \
-          | grep "^$(git show "$i" | git patch-id | cut -d " " -f 1)" \
-          | cut -d " " -f 2)
-    fi
-    if [ -z "${hash}" ]; then
-     # We don't know which cherry-pick it is coming from, fall back to the new commit hash.
-     echo "$i"
-    else
-     echo "${hash}"
-    fi
-  done
-}
-
-# Generate the title of the release with the date from the release name ($1).
-function get_release_title() {
-  echo "Release ${1} ($(date +%Y-%m-%d))"
-}
-
-# Generate the release message to be added to the changelog
-# from the release notes for release $1
-# Args:
-#   $1: release name
-#   $2: release ref (default HEAD)
-#   $3: delimiter around the revision information (default none)
-function generate_release_message() {
-  local release_name="$1"
-  local branch="${2:-HEAD}"
-  local delimiter="${3-}"
-  local baseline="$(get_release_baseline "${branch}")"
-  local cherrypicks="$(get_cherrypicks "${branch}" "${baseline}")"
-
-  get_release_title "$release_name"
-  echo
-
-  if [ -n "${delimiter}" ]; then
-    echo "${delimiter}"
-  fi
-  __create_revision_information $baseline $cherrypicks
-  if [ -n "${delimiter}" ]; then
-    echo "${delimiter}"
-  fi
-
-  echo
-  get_release_notes "${branch}"
-}
-
-# Returns the release notes for the CHANGELOG.md taken from either from
-# the notes for a release candidate or from the commit message for a
-# full release.
-function get_full_release_notes() {
-  local release_name="$(get_full_release_name "$@")"
-
-  if [[ "${release_name}" =~ rc[0-9]+$ ]]; then
-    # Release candidate, we need to generate from the notes
-    generate_release_message "${release_name}" "$@"
-  else
-    # Full release, returns the commit message
-    git_commit_msg "$@"
-  fi
-}
diff --git a/scripts/release/release.sh b/scripts/release/release.sh
index e20541d..ddc9085 100755
--- a/scripts/release/release.sh
+++ b/scripts/release/release.sh
@@ -83,43 +83,6 @@
   fi
 }
 
-# Set the release name to $1 (and eventually the candidate number to $2).
-function __set_release_name() {
-  git notes --ref=release remove 2>/dev/null || true
-  git notes --ref=release-candidate remove 2>/dev/null || true
-  git notes --ref=release append -m "$1"
-  if [[ ! -z "${2-}" ]]; then
-    git notes --ref=release-candidate append -m "$2"
-  fi
-}
-
-# Trim empty lines at the beginning and the end of the buffer.
-function __trim_empty_lines() {
-  # Replace all new line by a linefeed, then using sed, remove the leading
-  # and trailing linefeeds and convert them back to newline
-  tr '\n' '\f' | sed -e "s/^\f*//" -e "s/\f*$//" | tr '\f' '\n'
-}
-
-# Launch the editor and return the edited release notes.
-function __release_note_editor() {
-  local tmpfile="$1"
-  local branch_name="${2-}"
-
-  $EDITOR ${tmpfile} || {
-    echo "Editor failed, cancelling release creation..." >&2
-    return 1
-  }
-
-  # Strip the release notes.
-  local relnotes="$(cat ${tmpfile} | grep -v '^#' | __trim_empty_lines)"
-  if [ -z "${relnotes}" ]; then
-    echo "Release notes are empty, cancelling release creation..." >&2
-    return 1
-  fi
-
-  echo "${relnotes}" > "${tmpfile}"
-}
-
 # Create the release commit by changing the CHANGELOG file
 function __create_release_commit() {
   local infos=$(generate_release_message "${1}" HEAD '```')
@@ -161,29 +124,14 @@
         return 1
       fi
     }
-    # Add the origin of the cherry-pick in case the patch-id diverge and we cannot
-    # find the original commit.
-    git notes --ref=cherrypick add -f -m "${commit}"
   done
   return 0
 }
 
-# Find out the last release since the fork between HEAD from master.
-function __find_last_release() {
-  local baseline="${1:-$(get_release_baseline "HEAD")}"
-  local changes="$(git log --pretty=format:%H "${baseline}~".."${branch}")"
-  for change in ${changes}; do
-    if git notes --ref=release show ${change} &>/dev/null; then
-      echo ${change}
-      return 0
-    fi
-  done
-}
-
 # Execute the create command:
 #   Create a new release named "$1" with "$2" as the baseline commit.
 function __create_release() {
-  local force_rc=
+  local force_rc=1
   if [[ "$1" =~ ^--force_rc=([0-9]*)$ ]]; then
     force_rc=${BASH_REMATCH[1]}
     shift 1
@@ -191,13 +139,11 @@
   local release_name="$1"
   local baseline="$2"
   shift 2
-  local branch_name="release-${release_name}"
+  local branch_name="release-${release_name}rc${force_rc}"
 
   # Fetch everything from remote repositories to avoid conflicts
   git fetch -f "${RELEASE_REPOSITORY}"
-  git fetch -f "${RELEASE_REPOSITORY}" 'refs/notes/*:refs/notes/*'
 
-  local last_release="$(git rev-parse --verify "${branch_name}" 2>/dev/null || true)"
   echo "Creating new release branch ${branch_name} for release ${release_name}"
   git checkout -B ${branch_name} ${baseline}
 
@@ -207,98 +153,9 @@
     exit 1
   }
 
-  __setup_git_notes "${force_rc}" "${release_name}" "${last_release}" || {
-    git checkout master
-    git branch -D ${branch_name}
-    exit 1
-  }
-
   echo "Created $(get_full_release_name) on branch ${branch_name}."
 }
 
-# Setup the git notes for a release.
-# It looks in the history since the merge base with master to find
-# the latest release candidate and create the git notes for:
-#   the release name (ref=release)
-#   the release candidate number (ref=release-candidate)
-#   the release notes (ref=release-notes)
-# Args:
-#   $1: set to a number to force the release candidate number (default
-#       is taken by increasing the previous release candidate number).
-#   $2: (optional) Specify the release name (default is taken by the
-#       last release candidate or the branch name, e.g. if the branch
-#       name is release-v1, then the name will be 'v1').
-#   $3: (optional) Specify the commit for last release.
-function __setup_git_notes() {
-  local force_rc="$1"
-  local branch_name="$(git_get_branch)"
-
-  # Figure out where we are in release: find the rc, the baseline, cherrypicks
-  # and release name.
-  local rc=${force_rc:-1}
-  local baseline="$(get_release_baseline "HEAD")"
-  local cherrypicks="$(get_cherrypicks "HEAD" "${baseline}")"
-  local last_release="${3-$(__find_last_release "${baseline}")}"
-  local release_name="${2-}"
-  if [ -n "${last_release}" ]; then
-    if [ -z "${force_rc}" ]; then
-      rc=$(($(get_release_candidate "${last_release}")+1))
-    fi
-    if [ -z "${release_name}" ]; then
-      release_name="$(get_release_name "${last_release}")"
-    fi
-  elif [ -z "${release_name}" ]; then
-    if [[ "${branch_name}" =~ ^release-(.*)$ ]]; then
-      release_name="${BASH_REMATCH[1]}"
-    else
-      echo "Cannot determine the release name." >&2
-      echo "Please create a release branch with the name release-<name>." >&2
-      return 1
-    fi
-  fi
-
-  # Edit the release notes
-  local tmpfile=$(mktemp --tmpdir relnotes-XXXXXXXX)
-  trap "rm -f ${tmpfile}" EXIT
-
-  echo "Creating release notes"
-
-  # Save the changelog so we compute the relnotes against HEAD.
-  git show master:CHANGELOG.md > "${tmpfile}"
-
-  # Compute the new release notes
-  local relnotes="$(create_release_notes "${tmpfile}" "${baseline}" ${cherrypicks})"
-
-  # Try to merge the release notes if there was a previous release
-  if [ -n "${last_release}" ]; then
-    # Compute the previous release notes
-    local last_baseline="$(get_release_baseline "${last_release}")"
-    git checkout -q "${last_release}"
-    local last_relnotes="$(create_release_notes "${tmpfile}")"
-    git checkout -q "${branch_name}"
-    local last_savedrelnotes="$(get_release_notes "${last_release}")"
-    relnotes="$(__merge_release_notes "${branch_name}" "${relnotes}" \
-      "${last_relnotes}" "${last_savedrelnotes}")"
-  fi
-
-  echo "${RELEASE_NOTE_MESSAGE}" > "${tmpfile}"
-  echo "# $(get_release_title "${release_name}rc${rc}")" >> "${tmpfile}"
-  echo >> "${tmpfile}"
-  echo "${relnotes}" >> "${tmpfile}"
-
-  __release_note_editor "${tmpfile}" "${branch_name}" || return 1
-  relnotes="$(cat ${tmpfile})"
-
-  # Add the git notes.
-  git notes --ref=release add -f -m "${release_name}"
-  git notes --ref=release-candidate add -f -m "${rc}"
-  git notes --ref=release-notes add -f -m "${relnotes}"
-
-  # Clean-up.
-  rm -f "${tmpfile}"
-  trap - EXIT
-}
-
 # Force push a ref $2 to repo $1 if exists
 function __push_if_exists() {
   if git show-ref -q "${2}"; then
@@ -306,28 +163,28 @@
   fi
 }
 
-# Push release notes refs but also a given ref
-function __push_notes_and_ref() {
+# Push a given ref
+function __push_ref() {
   local ref="$1"
   __push_if_exists "${RELEASE_REPOSITORY}" "${ref}"
-  __push_if_exists "${RELEASE_REPOSITORY}" "refs/notes/release"
-  __push_if_exists "${RELEASE_REPOSITORY}" "refs/notes/release-candidate"
-  __push_if_exists "${RELEASE_REPOSITORY}" "refs/notes/release-notes"
-  __push_if_exists "${RELEASE_REPOSITORY}" "refs/notes/cherrypick"
 }
 
 # Push the release branch to the release repositories so a release
 # candidate can be created.
 function __push_release_candidate() {
-  __push_notes_and_ref "$(get_release_branch)"
+  __push_ref "$(get_release_branch)"
 }
 
 # Deletes the release branch after a release or abandoning the release
 function __cleanup_branches() {
   local tag_name=$1
   echo "Destroying the release branches for release ${tag_name}"
-  git branch -D "release-${tag_name}" &>/dev/null || true
-  git push -f "${RELEASE_REPOSITORY}" ":release-${tag_name}" &>/dev/null || true
+  for branch in $(git branch | grep -Po "release-${tag_name}rc([0-9])*")
+  do
+    echo "Deleting ${branch}"
+    git branch -D "${branch}" &>/dev/null || true
+    git push -f "${RELEASE_REPOSITORY}" ":${branch}" &>/dev/null || true
+  done
 }
 
 # Releases the current release branch, creating the necessary tag,
@@ -336,15 +193,13 @@
 function __do_release() {
   local branch=$(get_release_branch)
   local tag_name=$(get_release_name)
+  local candidate=$(get_release_candidate)
 
   echo -n "You are about to release branch ${branch} in tag ${tag_name}, confirm? [y/N] "
   read answer
   if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then
     echo "Creating the release commit"
     __create_release_commit "${tag_name}"
-    __set_release_name "${tag_name}"
-    git notes --ref=release add -f -m "${tag_name}"
-    git notes --ref=release-candidate remove || true
 
     echo "Creating the tag"
     git tag ${tag_name}
@@ -369,7 +224,7 @@
 
     echo "Pushing the change to remote repositories"
     git push "${MASTER_REPOSITORY}" +master
-    __push_notes_and_ref "refs/tags/${tag_name}"
+    __push_ref "refs/tags/${tag_name}"
     __cleanup_branches "${tag_name}"
   fi
 }
@@ -379,13 +234,12 @@
 function __abandon_release() {
   local branch_info=$(get_release_branch)
   local tag_name=$(get_release_name)
+  local candidate=$(get_release_candidate)
   echo -n "You are about to abandon release ${tag_name}, confirm? [y/N] "
   read answer
   if [ "$answer" = "y" ] || [ "$answer" = "Y" ]; then
-    git notes --ref=release remove || true
-    git notes --ref=release-candidate remove || true
     git checkout -q master >/dev/null
-    __cleanup_branches ${tag_name}
+    __cleanup_branches "${tag_name}"
   fi
 }
 
@@ -399,13 +253,6 @@
       COMMIT1 ... COMMITN. The release candidate number will be
       computed from existing release branch unless --force_rc is
       specified.
-  - generate-rc [--force_rc=RC]: generate a release candidate out of
-      the current branch, the branch should be named "release-XXX"
-      where "XXX" is the name of the release. This branch should be
-      a fork of master in which some cherry-picks where taken from
-      master. --force_rc can be used to override the RC number
-      (by default it tries to look for latest release and increment
-      the rc number).
   - push: push the current release branch to release repositories.
   - release: do the actual release of the current release branch.
   - abandon: abandon the current release branch.
@@ -453,14 +300,6 @@
   release)
     __do_release
     ;;
-  generate-rc)
-    force_rc=
-    if [[ "${1-}" =~ ^--force_rc=([0-9]*)$ ]]; then
-      force_rc=${BASH_REMATCH[1]}
-      shift 1
-    fi
-    __setup_git_notes "${force_rc}"
-    ;;
   abandon)
     __abandon_release
     ;;
diff --git a/scripts/release/relnotes.sh b/scripts/release/relnotes.sh
index cacd4ba..b0182f2 100755
--- a/scripts/release/relnotes.sh
+++ b/scripts/release/relnotes.sh
@@ -18,8 +18,8 @@
 
 # Generate the release notes from the git history.
 
-SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
-source ${SCRIPT_DIR}/common.sh
+RELNOTES_SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+source ${RELNOTES_SCRIPT_DIR}/common.sh
 
 # It uses the RELNOTES tag in the history to knows the important changes to
 # report:
@@ -171,3 +171,149 @@
   [ -n "${last_release}" ] || { echo "Initial release."; return 0; }
   __release_notes ${last_release}
 }
+
+# Trim empty lines at the beginning and the end of the buffer.
+function __trim_empty_lines() {
+  # Replace all new line by a linefeed, then using sed, remove the leading
+  # and trailing linefeeds and convert them back to newline
+  tr '\n' '\f' | sed -e "s/^\f*//" -e "s/\f*$//" | tr '\f' '\n'
+}
+
+# Launch the editor and return the edited release notes.
+function __release_note_processor() {
+  local tmpfile="$1"
+
+  # Strip the release notes.
+  local relnotes="$(cat ${tmpfile} | grep -v '^#' | __trim_empty_lines)"
+  if [ -z "${relnotes}" ]; then
+    echo "Release notes are empty, cancelling release creation..." >&2
+    return 1
+  fi
+
+  echo "${relnotes}" > "${tmpfile}"
+}
+
+# Create the revision information given a list of commits. The first
+# commit should be the baseline, and the other ones are the cherry-picks.
+# The result is of the form:
+# Baseline: BASELINE_COMMIT
+#
+# Cherry picks:
+#
+#    + CHERRY_PICK1: commit message summary of the CHERRY_PICK1. This
+#                    message will be wrapped into 70 columns.
+#    + CHERRY_PICK2: commit message summary of the CHERRY_PICK2.
+function __create_revision_information() {
+  echo "Baseline: $(__git_commit_hash "${1}")"
+  local first=1
+  shift
+  while [ -n "${1-}" ]; do
+    if [[ "$first" -eq 1 ]]; then
+      echo -e "\nCherry picks:"
+      echo
+      first=0
+    fi
+    local hash="$(__git_commit_hash "${1}")"
+    local subject="$(__git_commit_subject $hash)"
+    local lines=$(echo "$subject" | wrap_text 65)  # 5 leading spaces.
+    echo "   + $hash:"
+    echo "$lines" | sed 's/^/     /'
+    shift
+  done
+}
+
+# Get the baseline of master.
+# Args: $1: release branch (or HEAD)
+# TODO(philwo) this gives the wrong baseline when HEAD == release == master.
+function get_release_baseline() {
+  git merge-base master "$1"
+}
+
+# Get the list of cherry-picks since master
+# Args:
+#   $1: branch, default to HEAD
+#   $2: baseline change, default to $(get_release_baseline $1)
+function get_cherrypicks() {
+  local branch="${1:-HEAD}"
+  local baseline="${2:-$(get_release_baseline "${branch}")}"
+  # List of changes since the baseline on the release branch
+  local changes="$(git_log_hash "${baseline}" "${branch}" --reverse)"
+  # List of changes since the baseline on the master branch, and their patch-id
+  local master_changes="$(git_log_hash "${baseline}" master | xargs git show | git patch-id)"
+  # Now for each changes on the release branch
+  for i in ${changes}; do
+    # Find the change with the same patch-id on the master branch if the note is not present
+    hash=$(echo "${master_changes}" \
+        | grep "^$(git show "$i" | git patch-id | cut -d " " -f 1)" \
+        | cut -d " " -f 2)
+    if [ -z "${hash}" ]; then
+     # We don't know which cherry-pick it is coming from, fall back to the new commit hash.
+     echo "$i"
+    else
+     echo "${hash}"
+    fi
+  done
+}
+
+# Generate the title of the release with the date from the release name ($1).
+function get_release_title() {
+  echo "Release ${1} ($(date +%Y-%m-%d))"
+}
+
+# Generate the release message to be added to the changelog
+# from the release notes for release $1
+# Args:
+#   $1: release name
+#   $2: release ref (default HEAD)
+#   $3: delimiter around the revision information (default none)
+function generate_release_message() {
+  local release_name="$1"
+  local branch="${2:-HEAD}"
+  local delimiter="${3-}"
+  local baseline="$(get_release_baseline "${branch}")"
+  local cherrypicks="$(get_cherrypicks "${branch}" "${baseline}")"
+
+  get_release_title "$release_name"
+  echo
+
+  if [ -n "${delimiter}" ]; then
+    echo "${delimiter}"
+  fi
+  __create_revision_information $baseline $cherrypicks
+  if [ -n "${delimiter}" ]; then
+    echo "${delimiter}"
+  fi
+
+  echo
+
+  # Generate the release notes
+  local tmpfile=$(mktemp --tmpdir relnotes-XXXXXXXX)
+  trap "rm -f ${tmpfile}" EXIT
+
+  # Save the changelog so we compute the relnotes against HEAD.
+  git show master:CHANGELOG.md > "${tmpfile}"
+
+  local relnotes="$(create_release_notes "${tmpfile}" "${baseline}" ${cherrypicks})"
+  echo "${relnotes}" > "${tmpfile}"
+
+  __release_note_processor "${tmpfile}" || return 1
+  relnotes="$(cat ${tmpfile})"
+
+  cat "${tmpfile}"
+}
+
+# Returns the release notes for the CHANGELOG.md taken from either from
+# the notes for a release candidate or from the commit message for a
+# full release.
+function get_full_release_notes() {
+  local release_name="$(get_full_release_name "$@")"
+
+  if [[ "${release_name}" =~ rc[0-9]+$ ]]; then
+    # Release candidate, we need to generate from the notes
+    generate_release_message "${release_name}" "$@"
+  else
+    # Full release, returns the commit message
+    git_commit_msg "$@"
+  fi
+}
+