[PATCH] scripts: Add a pre-receive hook to catch invalid merge and WIP commits

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This should make sure we avoid merge commits from branches outside of PA
(we don't really have any, so this should avoid all merge commits). This
also catches "WIP" and such in the title to prevent accidental pushing
of those.
---
 scripts/pre-receive.hook | 89 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 89 insertions(+)
 create mode 100755 scripts/pre-receive.hook

diff --git a/scripts/pre-receive.hook b/scripts/pre-receive.hook
new file mode 100755
index 0000000..7240c27
--- /dev/null
+++ b/scripts/pre-receive.hook
@@ -0,0 +1,89 @@
+#!/usr/bin/env python2
+import sys
+import os
+import subprocess
+
+# Based on the same file in: https://cgit.freedesktop.org/gstreamer/common
+# Manually deployed to /srv/git.freedesktop.org/git/pulseaudio/pulseaudio.git/hooks
+
+# checks whether the push contains merge commits and if so, makes sure that
+# the merge is only between branches present on the repository.
+def contains_valid_merge(old, new, ref):
+    sub = subprocess.Popen(["git", "rev-list", "--parents", "%s..%s" % (old, new, )],
+                           stdout=subprocess.PIPE)
+    stdout, stderr = sub.communicate()
+
+    res = True
+
+    print "=> Checking for merge commits"
+
+    for line in stdout.split('\n'):
+        if res == False:
+            break
+        splits = line.strip().split()
+        if len(splits) > 2:
+            # the commit has more than one parent => it's a merge
+            commit = splits[0]
+            for parent in splits[1:]:
+                if not commit_in_valid_branch(parent):
+                    print
+                    print "    /!\\ Commit %s" % commit
+                    print "    /!\\ is a merge commit from/to a branch not"
+                    print "    /!\\ present on this repository"
+                    print
+                    print "    Make sure you are not attempting to push a merge"
+                    print "    from a 3rd party repository"
+                    print
+                    print "    Make sure you have properly rebased your commits against"
+                    print "    the current official branches"
+                    print
+                    res = False
+                    break
+
+    if res:
+            print "   [OK]"
+            print
+    return res
+
+# checks whether the first line of any commit message contains a marker
+# that indicates that it's work-in-progress that shouldn't be pushed
+def contains_wip_commits(old, new):
+    # Get the commit message header
+    sub = subprocess.Popen(["git", "log", "--format=%s", "%s..%s" % (old, new, )], stdout=subprocess.PIPE)
+    stdout, stderr = sub.communicate()
+    if stdout != "":
+        for line in stdout.strip().rsplit('\n',1):
+            if line.startswith("!"):
+                return True
+            if line.startswith("WIP:") or line.startswith("wip:"):
+                return True
+    return False
+
+pushvalid = True
+error_badcommit = False
+
+for line in sys.stdin.readlines():
+    # ref is the ref to be modified
+    # old is the old commit it was pointing to
+    # new is the new commit it was pointing to
+    old, new, ref = line.split(' ', 2)
+
+    pushvalid = contains_valid_merge(old, new, ref)
+    if pushvalid == False:
+        break
+    if contains_wip_commits(old, new):
+        error_badcommit = True
+        pushvalid = False
+        break
+
+if pushvalid:
+    print "   Incoming packet valid, proceeding to actual commit"
+    print
+    sys.exit(0)
+else:
+    if error_badcommit:
+        print "   Attempting to push commits with commit messages that start"
+        print "   with '!' or 'WIP:'. Such commit messages are reserved for"
+        print "   private branches and work in progress to prevent the commits"
+        print "   from accidentally being pushed to the main repository."
+    sys.exit(-1)
-- 
2.9.3



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux