--- /dev/null
+#!/usr/bin/env python
+import sys
+import os
+import subprocess
+
+# This server-side pre-receive hook is to be put and activated in all modules
+# that depend on the common submodule.
+#
+# It will check whether any modifications to the common 'submodule file' has a
+# a valid commit SHA1 that exists in the common module.
+
+def commit_exists(sha1, gitdir):
+ """Returns True if the sha1 is a valid commit in the given
+ git directory"""
+ # FIXME: We're using 'git show' for the time being, but there's a small
+ # risk that there might be a valid SHA1 for a non-commit object.
+ env = os.environ.copy()
+ env["GIT_DIR"] = gitdir
+ sub = subprocess.Popen(["git", "show", sha1], env=env,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ while True:
+ res = sub.poll()
+ if res != None:
+ return res == 0
+
+# location of the common git module
+COMMON_GIT_DIR = "/git/gstreamer/common.git"
+
+pushvalid = True
+error_badcommon = False
+error_badcommit = False
+
+print "=> Checking for integrity of common submodule changes"
+print
+
+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)
+
+ # 1. Get the latest change to common (if there was any changes)
+ sub = subprocess.Popen(["git", "diff", "%s..%s" % (old, new, ), "--", "common"],
+ stdout=subprocess.PIPE)
+ stdout, stderr = sub.communicate()
+ if stdout != "":
+ # Format of submodule special files
+ # Subproject commit <SHA1>
+
+ # we get a diff, therefore only grab the last line
+ lastline = stdout.strip().rsplit('\n',1)[-1]
+ if not lastline.startswith("+Subproject commit"):
+ # this is bad, it means the diff has changed to something completely
+ # different
+ continue
+ subsha1 = lastline.rsplit(' ', 1)[-1]
+ print " Pack wants common to point to", subsha1
+ if not commit_exists(subsha1, COMMON_GIT_DIR):
+ print " /!\\ Commit does not exist in common git module /!\\"
+ print " /!\\ for ref", ref
+ pushvalid = False
+ break
+
+ # 2. Figure out if that commit exists in the common submodule
+ # (use GIT_DIR to execute commands in that directory)
+
+ # Get the commit message
+ 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("!"):
+ error_badcommit = True
+ pushvalid = False
+ break
+
+if pushvalid:
+ print " Incoming packet valid, proceeding to actual commit"
+ sys.exit(0)
+else:
+ if error_badcommit:
+ print " Attempting to push commits with commit messages that start"
+ print " with '!'. Commit messages starting with '!' are reserved"
+ print " for private branches to prevent the commits from accidentally"
+ print " getting to the main repository."
+ if error_badcommon:
+ print " Attempting to push commits containing modifications to common"
+ print " that have not been commited to the actuall common module."
+ print
+ print " First push your changes to common/ before pushing the changes"
+ print " to the module using it."
+ sys.exit(-1)
+