summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcheck-receive-policy15
-rwxr-xr-xcheck-rev-policy129
-rwxr-xr-xinstall-repos1
-rwxr-xr-xpre-receive20
4 files changed, 153 insertions, 12 deletions
diff --git a/check-receive-policy b/check-receive-policy
new file mode 100755
index 0000000..1956a07
--- /dev/null
+++ b/check-receive-policy
@@ -0,0 +1,15 @@
+#!/bin/sh -eu
+set -eu
+
+# Check if user is allowed
+user=`id -un`
+match=`test -f git-receive-allow && grep -Fx "$user" git-receive-allow || true`
+echo $match > /tmp/match.log
+if [ -z "$match" ]; then
+ cat <<EOF >&2
+---
+You're not allowed to push to this repository as $user.
+---
+EOF
+ exit 1
+fi
diff --git a/check-rev-policy b/check-rev-policy
new file mode 100755
index 0000000..c7f6c4e
--- /dev/null
+++ b/check-rev-policy
@@ -0,0 +1,129 @@
+#!/bin/sh -eu
+set -eu
+
+server=git.ws.local
+
+check_commit()
+{
+ commit=$1
+
+ # Check the email
+ email="`git log $commit -1 --pretty=format:%ae`"
+ case "$email" in
+ *localhost.localdomain|*\(none\))
+ cat <<EOF >&2
+---
+The commits you are trying to push contain the author email
+address '$email'. Please configure your
+name and email address.
+---
+EOF
+ exit 1
+ ;;
+ esac
+
+ subj="`git log $commit -1 --pretty=format:%s`"
+ case "$subj" in
+ *Merge\ branch*of*[gs][is][th]\:*)
+ cat <<EOF >&2
+---
+The commit:
+
+EOF
+ git log $commit -1 >&2
+ cat <<EOF >&2
+
+Looks like it was produced by typing 'git pull' without the --rebase
+option when you had local changes. Running 'git pull --rebase' now
+will fix the problem. Then please try, 'git push' again.
+---
+EOF
+ exit 1
+ ;;
+ esac
+}
+
+check_ref_update()
+{
+ oldrev=$1
+ newrev=$2
+ refname=$3
+
+ change_type=update
+ if expr $oldrev : "^0\+$" > /dev/null 2>&1; then
+ change_type=create
+ fi
+
+ if expr $newrev : "^0\+$" > /dev/null 2>&1; then
+ if [ x$change_type = xcreate ] ; then
+ # Deleting an invalid ref, allow
+ return 0
+ fi
+ change_type=delete
+ fi
+
+ case $refname in
+ refs/heads/*)
+ range=
+ case $change_type in
+ create)
+ range="$newrev"
+ ;;
+ update)
+ range="$oldrev..$newrev"
+ ;;
+ esac
+
+ if [ -n "$range" ]; then
+ for merged in `git rev-parse --symbolic-full-name \
+ --not --branches | egrep -v "^/^$refname$" | \
+ git rev-list --reverse --stdin "$range"`; do
+ check_commit $merged
+ done
+ fi
+ ;;
+
+ ref/tags/*)
+ ;;
+
+ # Remote tracking branch
+ ref/remotes/*)
+ cat <<EOF >&2
+---
+You are trying to push the remote tracking branch:
+
+ $refname
+
+to $server
+---
+EOF
+ exit 1
+ ;;
+
+ # Something completely different
+ *)
+ cat <<EOF >&2
+---
+You are trying to push the ref:
+
+ $refname
+
+to $server. This isn't a branch or tag.
+---
+EOF
+ exit 1
+ ;;
+ esac
+
+ return 0
+}
+
+if [ $# = 3 ] ; then
+ check_ref_update $@
+else
+ echo "usage: check-rev-policy oldrev newrev refname" >&2
+ exit 2
+fi
+
+exit 0
+
diff --git a/install-repos b/install-repos
index ae10f44..82518f2 100755
--- a/install-repos
+++ b/install-repos
@@ -16,6 +16,7 @@ for hook in $HOOKS; do
find . -type d -print0 | xargs -0 chmod 770
ln -sf $BASE/$hook hooks/$hook
git config core.sharedRepository=0660 || true
+ git config receive.denyNonFastforwards=true || true
touch git-daemon-export-ok
fi
done
diff --git a/pre-receive b/pre-receive
index 4232983..ec9c461 100755
--- a/pre-receive
+++ b/pre-receive
@@ -1,16 +1,12 @@
#!/bin/sh -eu
set -eu
-user=`id -un`
+BASE="/data/git/bin"
-# Check if user is allowed
-match=`test -f git-receive-allow && grep -Fx "$user" git-receive-allow || true`
-echo $match > /tmp/match.log
-if [ -z "$match" ]; then
- cat <<EOF >&2
----
-You're not allowed to push to this repository as $user.
----
-EOF
- exit 1
-fi
+# Check receive policy
+$BASE/check-receive-policy
+
+# Check commit policy for each one
+while read oldrev newrev refname; do
+ $BASE/check-rev-policy $oldrev $newrev $refname || exit 1
+done