#!/bin/bash # Announce a git branch die() { echo "$@" >> /dev/stderr exit 1 } helpme() { die "Usage: $0 [oldref] [newref] [remote] [branch] [--force] [--cc] [--review] [--tag tag]" } # Note: getopt requires -o '' or else it won't process positional arguments # correctly! TEMP=$(getopt -o '' --long 'cc,force,debug,review,tag:' -n "$0" -- "$@") test $? -eq 0 || helpme eval set -- "$TEMP" unset TEMP force=0 debug=0 cc= verb="announce" tags=() while true; do case "$1" in '--force') force=1; shift; continue;; '--debug') debug=1; shift; continue;; '--cc') cc=1; shift; continue;; '--review') verb="review"; shift; continue;; '--tag') tags+=("$2"); shift; shift; continue;; '--') shift; break;; *) helpme;; esac done oldref="$1" newref="$2" remote="$3" branch="$4" if [ -z "${oldref}" ]; then oldref="$(git branch-remote)" || exit 1 fi true "${newref:=HEAD}" true "${remote:=korg}" true "${branch:=for-next}" code_submit_tgt="$(git config user.codeSubmissionTarget)" test -n "${code_submit_tgt}" || \ die "${PWD}: code submission target not configured." # Does the oldref exist? git rev-list -n 0 "${oldref}" > /dev/null 2>&1 || \ die "${oldref}: starting git reference not found." # Make sure there's a series of commits between oldref and newref. nr_commits="$(git rev-list "${oldref}..${newref}" | wc -l)" # echo "${oldref}..${newref}; nr_commits = $nr_commits" > /dev/stderr test "${nr_commits}" -gt 0 || \ die "${oldref}..${newref}: Must have at least one commit." # Figure out the short name and the url of the remote repo. git ls-remote "${remote}" > /dev/null 2>&1 || die "${remote}: remote repo unknown." repo="$(basename "$(git remote get-url "${remote}")" | sed -e 's/\.git//g')" origin_url="$(git remote get-url "${remote}")" # Figure out the commit id for the newref (or the commit the tag points # to, if it's a tag). longid="$(git rev-list -n 1 "${newref}")" shortid="$(git rev-parse --short "${longid}")" test -n "${longid}" || die "${newref}: ending git reference not found." filter_commit() { local commit_id="$1" sed -e 's@refs/heads/@@g' | \ awk -v commit="${commit_id}" \ 'BEGIN{ret=1;}{if ($1 == commit) {print $2; ret=0; exit;}}END{exit(ret);}' } # Let's see if the default branch has the referenced commit? branch="$(git ls-remote "${remote}" "refs/heads/${branch}" | \ filter_commit "${longid}")" # Nope. Let's see if any of them have it. test -z "${branch}" && branch="$(git ls-remote --heads "${remote}" | \ filter_commit "${longid}")" test -n "${branch}" || die "${newref}: couldn't find a remote branch with this reference." # Check each commit for RVB and SOB. git checkpatch "${oldref}..${newref}" test $? -ne 0 && test "${force}" -eq 0 && exit 1 if [ -n "${cc}" ]; then echo "Cc: $(git contributors --delimiter ', ' "${oldref}..${newref}")" fi # Compute the ANNOUNCE tag contents. announce="[ANNOUNCE" for ((i = 0; i < ${#tags[@]}; i++)); do announce="${announce} ${tags[i]}" done announce="${announce}]" # Ok, emit announcement message. review_message() { cat << ENDL Subject: ${announce} ${repo}: ${branch} updated to ${shortid} Hi folks, The ${branch} branch of the ${repo} repository at: ${origin_url} has just been updated for your review. This code snapshot has been rebased against recent upstream, freshly QA'd, and is ready for people to examine. For veteran readers, the new snapshot can be diffed against the previous snapshot; and for new readers, this is a reasonable place to begin reading. For the best experience, it is recommended to pull this branch and walk the commits instead of trying to read any patch deluge. The new head of the ${branch} branch is commit: ENDL } announce_message() { cat << ENDL Subject: ${announce} ${repo}: ${branch} updated to ${shortid} Hi folks, The ${branch} branch of the ${repo} repository at: ${origin_url} has just been updated. Patches often get missed, so please check if your outstanding patches were in this update. If they have not been in this update, please resubmit them to ${code_submit_tgt} so they can be picked up in the next update. The new head of the ${branch} branch is commit: ENDL } "${verb}_message" git log --oneline -n 1 "${oldref}..${newref}" | cat - echo if [ "${nr_commits}" -eq 1 ]; then echo "${nr_commits} new commit:" else echo "${nr_commits} new commits:" fi echo git shortlog --format="[%h] %s" "${oldref}..${newref}" fs/xfs Documentation/ | cat - echo Code Diffstat: echo git diff --stat --summary -C -M "${oldref}..${newref}" fs/xfs Documentation/ | cat -