#!/usr/bin/env bash # # Generate a mail feed for a commits list. # # Author: David Woodhouse # Environment variables used by this script... # # $SENDMAIL and $MLIST must be set appropriately if you intend to # actually send mail to a mailing list (or other recipient). Otherwise, # an mbox file named 'git commits-mail.out' will be created in the # current directory. # # $FROM specifies the From: header used in the mails. It'll default # to GIT_COMMITTER_EMAIL if that exists, or to `whoami`@`hostname` # # $EXCLUDEHEAD is given as additional arguments to the git rev-list # invocation, and is intended to allow other branches to be excluded. # For example, subsystem trees might avoid mailing changes which were # merged in from Linus' tree by setting EXCLUDEHEAD=^linus # # $GIT_DIR has the obvious effect. # # $MAILTAG specifies the file in which the 'last commit mailed' information # is stored. By default, this will be $GIT_DIR/refs/tags/MailDone, or # just the relative path '.git/refs/tags/MailDone' if $GIT_DIR is not specified # # GITWEB specifies the base URL to gitweb for this repository if [ -z "SENDMAIL" -o -z "$MLIST" ]; then SENDMAIL="tee --append" MLIST=git commits-mail.out fi if [ -z "$FROM" ]; then if [ -n "$GIT_COMMITTER_EMAIL" ]; then FROM="$GIT_COMMITTER_EMAIL" else FROM=`whoami`@`hostname` fi fi if [ -z "$MAILTAG" ]; then if [ "$GIT_DIR" = "" ]; then MAILTAG=.git/refs/tags/MailDone else MAILTAG=$GIT_DIR/refs/tags/MailDone fi fi # Command line arguments. The first specifies the commit or branch to treat # as HEAD, and the second is the starting commit. Defaults to HEAD and # whatever's in $MAILTAG, resp. if [ -z $2 ]; then lastmail=$(git rev-parse `cat $MAILTAG`) if [ -z "$lastmail" ]; then echo "No last tag" exit 1 fi else lastmail=$(git rev-parse $2) fi if [ -z $1 ]; then base=$(git rev-parse HEAD) || exit 1 else base=$(git rev-parse $1) || exit 1 fi if [ "$base" != "$lastmail" ]; then git rev-list --topo-order --no-merges $lastmail..$base $EXCLUDEHEAD | tac | while read COMMIT ; do ( PARENT=`git rev-parse $COMMIT^1` # SUBJECT="`git show --pretty=oneline $COMMIT | head -2 | tail -1`" SUBJECT="`git cat-file commit $COMMIT | grep -A1 ^\$ | head -2 | tail -1`" echo Mail: $SUBJECT >&2 SUBHEX="`echo -n "$SUBJECT" | od -t x1 -A none | tr a-f A-F`" if echo $SUBHEX | egrep -q ' [8-9A-F]' ; then # Subject contains non-ASCII. WORDLEN=10 NEWSUB="=?UTF-8?Q?" for CHR in $SUBHEX ; do if [ $WORDLEN -gt 70 ]; then NEWSUB="${NEWSUB}?= =?UTF-8?Q?" WORDLEN=10 fi case $CHR in 20) NEWSUB="${NEWSUB}_" WORDLEN=$((WORDLEN+1)) ;; 0*|1*|3D|3F|5F|7F|8*|9*|A*|B*|C*|D*|E*|F*) NEWSUB="${NEWSUB}=$CHR" WORDLEN=$(($WORDLEN+3)) ;; *) NEWSUB="${NEWSUB}`echo -en \\\\x$CHR`" WORDLEN=$((WORDLEN+1)) ;; esac done SUBJECT="$NEWSUB?=" fi cat < $MAILTAG fi