>From 391666fda49fef9ac003d192e7ae8a3c2b00e113 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Mon, 28 Sep 2015 13:46:39 +0200 Subject: [PATCH] contrib: Add a pre-push hook to warn about commits without Reviewed-By --- contrib/git/pre-push | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100755 contrib/git/pre-push diff --git a/contrib/git/pre-push b/contrib/git/pre-push new file mode 100755 index 0000000000000000000000000000000000000000..b3f70a3c4cc684da469be8554c6604a848067904 --- /dev/null +++ b/contrib/git/pre-push @@ -0,0 +1,62 @@ +#!/usr/bin/env python + +# A git pre-push hook that declines commits that don't contain a Reviewed-By: +# tag. The tag must be present on the beginning of the line. + +import sys +import re +import subprocess + +def get_all_commits(ref_from, ref_to): + args = [ 'git', 'rev-list', '{:s}..{:s}'.format(ref_from, ref_to) ] + p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = p.communicate() + return [ commit.strip() for commit in out.split('\n') if commit != '' ] + +def commit_message(commit_hash): + args = [ 'git', 'cat-file', 'commit', commit_hash ] + p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + out, err = p.communicate() + return out + +def commit_has_rb(commit): + msg = commit_message(commit) + for l in msg.split('\n'): + has_rb = re.search('^Reviewed-by:', l) + if has_rb: + return True + + return False + +def report_commit(commit_hash): + print('Commit %s does not have Reviewed-By!' % commit_hash) + print('Full message:\n======\n%s======\n' % commit_message(commit_hash)) + +# man 5 githooks says: +# Information about what is to be pushed is provided on the hook's +# standard input with lines of the form: +# SP SP SP LF +def check_push(hook_input): + ref_to = hook_input.split()[1][:6] + ref_from = hook_input.split()[3][:6] + commit_list = get_all_commits(ref_from, ref_to) + + no_rb_list = [] + for commit in commit_list: + if not commit_has_rb(commit): + no_rb_list.append(commit) + + return no_rb_list + +# Don't warn when pushing to personal repositories, only origin +remote = sys.argv[1] +if remote != 'origin': + sys.exit(0) + +for hook_input in sys.stdin.readlines(): + no_rb_list = check_push(hook_input) + + if len(no_rb_list) > 0: + for offender in no_rb_list: + report_commit(offender) + sys.exit(1) -- 2.4.3