summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2015-09-28 13:46:39 +0200
committerLukas Slebodnik <lslebodn@redhat.com>2015-10-02 12:56:53 +0200
commit43147a9abaa1254235b853e643514cf1c7b150d7 (patch)
tree068be341f22c211840c322d8ea435e3b455ff4ca
parent8c9ecf0bd04be87a61d5f0e490ab8a7c48f481dd (diff)
downloadsssd-43147a9abaa1254235b853e643514cf1c7b150d7.tar.gz
sssd-43147a9abaa1254235b853e643514cf1c7b150d7.tar.xz
sssd-43147a9abaa1254235b853e643514cf1c7b150d7.zip
contrib: Add a pre-push hook to warn about commits without Reviewed-By
-rwxr-xr-xcontrib/git/pre-push73
1 files changed, 73 insertions, 0 deletions
diff --git a/contrib/git/pre-push b/contrib/git/pre-push
new file mode 100755
index 000000000..d05202dfd
--- /dev/null
+++ b/contrib/git/pre-push
@@ -0,0 +1,73 @@
+#!/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. To activate, copy
+# to $GIT_DIR/hooks/pre-push and make sure the executable flag is on.
+
+# The commit message should also be based on .git-commit-template, although
+# that is just best practice and not enforced
+
+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!".format(commit_hash))
+ print("Full message:\n======")
+ print("{:s}".format(commit_message(commit_hash)))
+ print("======")
+
+
+# man 5 githooks says:
+# Information about what is to be pushed is provided on the hook's
+# standard input with lines of the form:
+# <local ref> SP <local sha1> SP <remote ref> SP <remote sha1> 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)