We've all wanted to be able to tweak a few server-side settings,
without having to find/ask/wait for someone do something manually
on the server. With this change to ovirt's "update" hook,
you can now do just that by pushing a specially formed tag to
the remote repository. (once this hook is installed) If that tag meets
several criteria, the "update" hook will run the command you choose.
Of course, security is important here. We don't allow arbitrary
commands, but only those specified explicitly by some server
repository administrator. See the examples in the comments below.
>From f9c6f5c09c963392d0e04fa626ad7255ad4be734 Mon Sep 17 00:00:00 2001
From: Jim Meyering <meyering at redhat.com>
Date: Tue, 22 Sep 2009 17:17:24 +0200
Subject: [PATCH release] update hook: allow people to change server-side git
config
---
git-hook/update | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/git-hook/update b/git-hook/update
index ed76bd2..f98a403 100755
--- a/git-hook/update
+++ b/git-hook/update
@@ -41,6 +41,45 @@
# When this boolean is true, you may not push a merge commit to BRANCH_NAME.
# By default, you may.
#
+# ---------------------------------------------------------------------
+# Allow people to change server-side git config in very specific ways.
+# To enable this, on the server, you must do something like the following,
+#
+# git config hooks.server.config-changing.valid-commands \
+# 'git config hooks.allowbadwhitespace true
+# git config hooks.allowbadwhitespace false
+# git config hooks.denypush.branch.master master-branch-owner at example.com
+# git config --unset hooks.denypush.branch.master'
+#
+# where the git config variable, hooks.server.config-changing.valid-commands,
+# contains the list of commands that are allowed, one per line.
+#
+# CAUTION: nothing about this hook code enforces the restriction that
+# only "git config ..." commands be run automatically.
+# That restriction comes solely from the list above.
+#
+# Then, when someone with a cloned repository wants to make the hook
+# run one of those commands *on* *the* *server*, that user must push
+# a tag whose name starts with "git-control-" and whose one-line
message
+# matches exactly one of the listed commands.
+#
+# For example, to temporarily allow someone to push a bad-whitespace
+# commit, with the settings implied above, you might do this:
+#
+# first_commit=$(git log --reverse --pretty=%H |head -1)
+# git tag -m 'git config hooks.allowbadwhitespace true' \
+# git-control-$(date +%F-%H-%M-%S.%N) $first_commit
+#
+# Note that we're not tagging HEAD, but rather the very first commit
+# in the repository, in an attempt not to clutter up gitk/gitweb
+# displays with these rarely-interesting tag names.
+#
+# Then, to reenable that hook, do this (nearly the same, except s/true/false/):
+#
+# first_commit=$(git log --reverse --pretty=%H |head -1)
+# git tag -m 'git config hooks.allowbadwhitespace false' \
+# git-control-$(date +%F-%H-%M-%S.%N) $first_commit
+# ---------------------------------------------------------------------
# --- Command line
refname="$1"
@@ -109,6 +148,26 @@ case "$refname","$newrev_type" in
fi
;;
refs/tags/*,tag)
+ case $refname in
+ refs/tags/git-control-*)
+ cmd=$(git cat-file -p $newrev|tail -n+6)
+ git config hooks.server.config-changing.valid-commands |
+ (while read v_cmd; do
+ if test "x$cmd" = "x$v_cmd"; then
+ echo Running cmd: "$v_cmd"
+ eval "$v_cmd"
+ match=1
+ exit 0 # found a match
+ fi
+ done
+ exit 1 # signal failure to match
+ )
+ if test $? = 1; then
+ echo "*** unrecognized directive: $cmd" >&2
+ exit 1
+ fi
+ ;;
+ esac
# annotated tag
if [ "$allowmodifytag" != "true" ] && git
rev-parse $refname > /dev/null 2>&1
then
--
1.6.5.rc1.220.g6de7f