[Ovirt-devel] [PATCH release] server-side git hook: improve merge detection/prohibition
Jim Meyering
jim at meyering.net
Mon Mar 23 19:34:20 UTC 2009
FYI, I've just pushed this to the vcs-admin branch of "ovirt-release",
and am about to install it on the server, so it won't be possible to
produce another "diamond" like you currently see in ovirt-node.
>From 458d8b1df86a0f4ba9b3ae335e058a2afb04e698 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering at redhat.com>
Date: Mon, 23 Mar 2009 20:29:04 +0100
Subject: [PATCH release] improve merge detection/prohibition
* update: Document hooks.denymerge.BRANCH_NAME.
When looking for merge commits, check all that are being pushed,
not just the first one.
---
git-hook/update | 48 ++++++++++++++++++++++++++++++++++++++++++------
1 files changed, 42 insertions(+), 6 deletions(-)
mode change 100644 => 100755 git-hook/update
diff --git a/git-hook/update b/git-hook/update
old mode 100644
new mode 100755
index 9c80b36..c82015e
--- a/git-hook/update
+++ b/git-hook/update
@@ -1,7 +1,7 @@
#!/bin/sh
#
# An example hook script to blocks unannotated tags from entering.
-# Called by git-receive-pack with arguments: refname sha1-old sha1-new
+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
#
# To enable this hook, rename this file to "update".
#
@@ -16,6 +16,11 @@
# hooks.allowdeletebranch
# This boolean sets whether deleting branches will be allowed in the
# repository. By default they won't be.
+#
+# hooks.allowbadwhitespace
+# This boolean sets whether you may push a commit that adds bad whitespace.
+# By default, you may not.
+#
# hooks.denypush.branch.BRANCH_NAME
# If defined to a string that looks like an email address, this option
# disables push access to the specified branch. When a push fails as
@@ -23,14 +28,24 @@
# email address. For example, run this on the server to deny all push
# access to "master":
#
+# For example, enable it with this:
# git config hooks.denypush.branch.master master-branch-owner at example.com
#
+# hooks.denymerge.BRANCH_NAME
+# When this boolean is true, you may not push a merge commit to BRANCH_NAME.
+# By default, you may.
+#
# --- Command line
refname="$1"
oldrev="$2"
newrev="$3"
+is_merge_commit()
+{
+ git rev-parse --verify --quiet $1^2 > /dev/null
+}
+
# --- Safety check
if [ -z "$GIT_DIR" ]; then
echo "Don't run this script from the command line." >&2
@@ -51,17 +66,19 @@ allowdeletetag=$(git config --bool hooks.allowdeletetag)
# check for no description
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
-if [ -z "$projectdesc" -o "$projectdesc" = "Unnamed repository; edit this file to name it for gitweb." ]; then
+case "$projectdesc" in
+"Unnamed repository"* | "")
echo "*** Project description file hasn't been set" >&2
exit 1
-fi
+ ;;
+esac
# --- Check types
# if $newrev is 0000...0000, it's a commit to delete a ref.
if [ "$newrev" = "0000000000000000000000000000000000000000" ]; then
newrev_type=delete
else
- newrev_type=$(git-cat-file -t $newrev)
+ newrev_type=$(git cat-file -t $newrev)
fi
check_diff=no
@@ -87,15 +104,34 @@ case "$refname","$newrev_type" in
;;
refs/heads/*,commit)
# branch
- check_diff=yes
+ check_diff=yes
branch=${1##refs/heads/}
deny_push_email=$(git config "hooks.denypush.branch.$branch")
case $deny_push_email in
'') ;;
- *) printf "$0: %s\n" "commit on branch '$branch'" \
+ *) printf "error: *** %s\n" \
+ "commit on branch '$branch'" \
"locked by $deny_push_email" >&2
exit 1;;
esac
+
+ # When enabled, this prohibits pushing a merge commit.
+ # Enable this hook for branch "next" with e.g.,
+ # git config --bool hooks.denymerge.next true
+ deny_merge=$(git config --bool "hooks.denymerge.$branch")
+ case $deny_merge in
+ true)
+ for r in $(git rev-list $newrev ^$oldrev); do
+ is_merge_commit $r && {
+ printf "error: *** %s\n" \
+ "You may not push merge commits to branch $branch." \
+ "Did you forget to rebase? ($r)" >&2
+ exit 1
+ }
+ done
+ ;;
+ esac
+
;;
refs/heads/*,delete)
# delete branch
--
1.6.2.rc1.285.gc5f54
More information about the ovirt-devel
mailing list