Title / Description
Code diff --git a/all/post-receive/generate-rev-diff.py b/all/post-receive/generate-rev-diff.py new file mode 100644 index 0000000..4d8715f --- /dev/null +++ b/all/post-receive/generate-rev-diff.py @@ -0,0 +1,140 @@ +''' +Prints a formatted diff for a revision for post-receive-email +''' + +import os +import sys +import hashlib +from string import Template + +from pygments import highlight +from pygments.token import Token +from pygments.lexers import DiffLexer +from pygments.formatters import HtmlFormatter +from pygments.styles.default import DefaultStyle, Generic + + +sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) +import tools.git as git +import tools.util as util + +table = Template( +'''<table style="border: 1px solid #afafaf; cellpadding: 0; cellspacing: 20px;"> + $rows + </table>''') + +template = Template( +''' +<tr style="${tr_style}"> + <td> + <img src="http://www.gravatar.com/avatar/${gravatar_hash}?s=40"> + </td> + <td> + <h3 style="padding: 0; margin: 0; font: bold 14px Arial;"><a style="text-decoration: none; color: #000;" href="$anchor_link">$summary</a></h3> + <p style="margin:0; margin-top: 5px; font: 11px Arial; color: #c0c0c0;"><span style="color: #000">$author</span> authored $date</p> + </td> +</tr> +''' +) + +individual_diff = Template(''' + +<a name="$anchor_name">$revHeader</a> +$diff_content_html + +''') + +email_with_summary = Template(''' +$summary + +<hr style="height: 2px; background-color: #efefef; color: #efefef;"> + +$diffs +''') + +email_one_commit = Template(''' +$diffs +''') + + + +def _anchor_link_for_rev(rev): + return "diff_" + rev + +def diff_for_revspec(revspec): + revs = git.rev_list(revspec) + + summary_text = [] + diffs = [] + + for i, rev in enumerate(revs): + summary = git.format_string(rev, '%s') + author = git.format_string(rev, '%an') + authoremail = git.format_string(rev, '%ae') + summarytruncated = util.ellipses(summary.strip().split('\n')[0], 80) + gravatar_hash = hashlib.md5(authoremail).hexdigest() + date = git.format_string(rev, '%ad', extra_opts='--date=local') + + anchor_name = _anchor_link_for_rev(rev) + anchor_link = "#" + anchor_name + + diff_content = git.show('-C --pretty=format:"" ' + rev) + + class MyStyle(DefaultStyle): + styles = { + Generic.Deleted: "bg:#fdd", + Generic.Inserted: "bg:#dfd" + } + + html_formatter = HtmlFormatter( + noclasses=True, + style=MyStyle + ) + + diff_content_html = highlight(diff_content, DiffLexer(), html_formatter) + + if i % 2 == 0: + tr_style = 'background: #efefef;' + else: + tr_style = '' + + context = dict( + summary = summary, + author = author, + authoremail = authoremail, + gravatar_hash = gravatar_hash, + anchor_link = anchor_link, + anchor_name = anchor_name, + date = date) + + summary_text.append(template.safe_substitute(util.extend(dict(), context, dict( + summary = summarytruncated, + tr_style = tr_style + )))) + + diffs.append(individual_diff.safe_substitute(util.extend(dict(), context, dict( + revHeader = table.safe_substitute(rows=template.safe_substitute(util.extend(dict(), context, dict( + summary = summary, + tr_style = '' + )))), + diff_content_html = diff_content_html + )))) + + if len(revs) == 1: + main_template = email_one_commit + else: + main_template = email_with_summary + + return main_template.safe_substitute( + summary = table.safe_substitute(rows='\n'.join(summary_text)), + diffs = '\n'.join(diffs)) + + +def main(): + revspec = sys.argv[1] + print diff_for_revspec(revspec) + + + +if __name__ == '__main__': + main() diff --git a/all/post-receive/post-receive-email b/all/post-receive/post-receive-email index 93ef370..dbca7e9 100755 --- a/all/post-receive/post-receive-email +++ b/all/post-receive/post-receive-email @@ -200,19 +200,14 @@ generate_email_header() # --- Email (all stdout will be the email) # Generate header cat <<-EOF - MIME-Version: 1.0 - Content-type: text/html; charset=iso-8859-1 - To: $recipients + <html> + <head> + <title> Subject: ${emailprefix} $(git log --pretty=format:"%cn" -1 $describe) ${change_type}d $refname_type: $projectdesc/$short_refname. - X-Git-Refname: $refname - X-Git-Reftype: $refname_type - X-Git-Oldrev: $oldrev - X-Git-Newrev: $newrev + </title> + <body> - <h2>$projectdesc received a push.</h2> - - <h3>$refname_type: $short_refname ${change_type}d</h3> -<pre> + <h2>$projectdesc $refname_type: $short_refname ${change_type}d</h2> EOF } @@ -244,18 +239,6 @@ generate_create_branch_email() # generate_update_branch_email() { - # The diffstat is shown from the old revision to the new revision. - # This is to show the truth of what happened in this change. - # There's no point showing the stat from the base to the new - # revision because the base is effectively a random revision at this - # point - the user will be interested in what this revision changed - # - including the undoing of previous revisions in the case of - # non-fast-forward updates. - echo "" - echo "Summary of changes:" - git diff-tree --stat --summary --find-copies-harder $oldrev..$newrev - - echo "" if [ -z "$rewind_only" ]; then echo "" echo $LOGBEGIN @@ -270,6 +253,8 @@ generate_update_branch_email() echo "No new revisions were added by this update." fi + echo "<pre>" + # Consider this: # 1 --- 2 --- O --- X --- 3 --- 4 --- N # @@ -356,6 +341,16 @@ generate_update_branch_email() fast_forward=1 fi + # The diffstat is shown from the old revision to the new revision. + # This is to show the truth of what happened in this change. + # There's no point showing the stat from the base to the new + # revision because the base is effectively a random revision at this + # point - the user will be interested in what this revision changed + # - including the undoing of previous revisions in the case of + # non-fast-forward updates. + git diff-tree --stat --summary --find-copies-harder $oldrev..$newrev + + # List all the revisions from baserev to newrev in a kind of # "table-of-contents"; note this list can include revisions that # have already had notification emails and is present to show the @@ -413,6 +408,8 @@ generate_update_branch_email() fi fi + echo "</pre>" + } # @@ -624,15 +621,24 @@ show_new_revisions() then git rev-list --pretty --stdin $revspec else - git rev-list --stdin $revspec | - while read onerev - do + p=`pwd` + export PYTHONPATH='/usr/local/lib/python2.4/site-packages' + python `dirname $p/$0`/generate-rev-diff.py $revspec + + #git rev-list --stdin $revspec | + #while read onerev + #do + + #echo "<pre>" + #summary=`git --no-pager show -s --format='%s' $onerev` + #author=`git --no-pager show -s --format='%an' $onerev` + #echo "<h4>$summary</h4>" #eval $(printf "$custom_showrev" $onerev) -git show -C --pretty=format:"Author: %cn%n%N%n%s%n%b" $onerev > gitlog.txt -export PYTHONPATH='/usr/local/lib/python2.4/site-packages' -pygmentize -O encoding=utf-8 -O noclasses=True -f html -l diff gitlog.txt | sed 's/line-height: 125%/line-height: 147%; font-family: Monaco, Consolas, Courier New; font-size: 12px;/' -pygmentize -O encoding=utf-8 -O noclasses=True -f html -l diff -o gitlogemail.html gitlog.txt - done +#git show -C --pretty=format:"Author: %an%n%N%n%s%n%b" $onerev > gitlog.txt +#pygmentize -O encoding=utf-8 -O noclasses=True -f html -l diff gitlog.txt | sed 's/line-height: 125%/line-height: 147%; font-family: Monaco, Consolas, Courier New; font-size: 12px;/' +#pygmentize -O encoding=utf-8 -O noclasses=True -f html -l diff -o gitlogemail.html gitlog.txt + #echo "</pre>" + #done fi } @@ -686,6 +692,6 @@ if [ -n "$1" -a -n "$2" -a -n "$3" ]; then else while read oldrev newrev refname do - generate_email $oldrev $newrev $refname | send_mail + generate_email $oldrev $newrev $refname | cat done fi diff --git a/all/pre-receive/0000-update-hooks.git.sh b/all/pre-receive/0000-update-hooks.git.sh index 303c587..64bd8a4 100755 --- a/all/pre-receive/0000-update-hooks.git.sh +++ b/all/pre-receive/0000-update-hooks.git.sh @@ -5,9 +5,9 @@ # GIT_HOOKS_DIR=`git rev-parse --git-dir`/hooks -echo "Updating hooks in $GIT_HOOKS_DIR..." +#echo "Updating hooks in $GIT_HOOKS_DIR..." pushd $GIT_HOOKS_DIR -git fetch origin -git reset --hard origin/master +#git fetch origin +#git reset --hard origin/master popd -echo "done" +#echo "done" diff --git a/all/tools/git.py b/all/tools/git.py index fd88f5c..45502ea 100644 --- a/all/tools/git.py +++ b/all/tools/git.py @@ -1,5 +1,20 @@ import util +from subprocess import Popen, PIPE +def rev_list(revspec): + return Popen("git rev-list " + revspec, stdout=PIPE, shell=True).communicate()[0].split() + +def format_string(rev, format_string, extra_opts=''): + '''Formats a string for the given revision with the rules given in + git-diff-tree's "pretty formats" section.''' + + return Popen("git --no-pager show -s --date=short --format='" + format_string + "' " + extra_opts + ' ' + rev, + shell=True, stdout=PIPE).communicate()[0].strip() + +def show(args): return git('show ' + args) + +def git(args): + return Popen("git " + args, stdout=PIPE, shell=True).communicate()[0] def config(): c = {} diff --git a/all/tools/util.py b/all/tools/util.py index dfffe84..5481347 100644 --- a/all/tools/util.py +++ b/all/tools/util.py @@ -4,6 +4,22 @@ from os.path import join, abspath import contextlib import subprocess +def extend(*args): + if not args: return dict() + + args = list(args) + + d = args.pop(0) + while args: + d.update(args.pop(0)) + + return d + +def ellipses(text, limit=80): + if len(text) <= limit: + return text + + return text[:limit] + '...' @contextlib.contextmanager def cd(*dirs):
Author
Highlight as C C++ CSS Clojure Delphi ERb Groovy (beta) HAML HTML JSON Java JavaScript PHP Plain text Python Ruby SQL XML YAML diff code