Code

Documentation: add hooks/update example.
authorJunio C Hamano <junkio@cox.net>
Sun, 20 Nov 2005 07:50:48 +0000 (23:50 -0800)
committerJunio C Hamano <junkio@cox.net>
Sun, 20 Nov 2005 07:50:48 +0000 (23:50 -0800)
Signed-off-by: Junio C Hamano <junkio@cox.net>
Documentation/howto/update-hook-example.txt [new file with mode: 0644]

diff --git a/Documentation/howto/update-hook-example.txt b/Documentation/howto/update-hook-example.txt
new file mode 100644 (file)
index 0000000..dacaf17
--- /dev/null
@@ -0,0 +1,105 @@
+From: Junio C Hamano <junkio@cox.net>
+Subject: control access to branches.
+Date: Thu, 17 Nov 2005 23:55:32 -0800
+Message-ID: <7vfypumlu3.fsf@assigned-by-dhcp.cox.net>
+Abstract: An example hooks/update script is presented to
+ implement repository maintenance policies, such as who can push
+ into which branch and who can make a tag.
+
+When your developer runs git-push into the repository,
+git-receive-pack is run (either locally or over ssh) as that
+developer, so is hooks/update script.  Quoting from the relevant
+section of the documentation:
+
+    Before each ref is updated, if $GIT_DIR/hooks/update file exists
+    and executable, it is called with three parameters:
+
+           $GIT_DIR/hooks/update refname sha1-old sha1-new
+
+    The refname parameter is relative to $GIT_DIR; e.g. for the
+    master head this is "refs/heads/master".  Two sha1 are the
+    object names for the refname before and after the update.  Note
+    that the hook is called before the refname is updated, so either
+    sha1-old is 0{40} (meaning there is no such ref yet), or it
+    should match what is recorded in refname.
+
+So if your policy is (1) always require fast-forward push
+(i.e. never allow "git-push repo +branch:branch"), (2) you
+have a list of users allowed to update each branch, and (3) you
+do not let tags to be overwritten, then:
+
+       #!/bin/sh
+       # This is a sample hooks/update script, written by JC
+        # in his e-mail buffer, so naturally it is not tested
+        # but hopefully would convey the idea.
+
+       umask 002
+        case "$1" in
+        refs/tags/*)
+               # No overwriting an existing tag
+               if test -f "$GIT_DIR/$1"
+                then
+                       exit 1
+               fi
+               ;;
+       refs/heads/*)
+               # No rebasing or rewinding
+                if expr "$2" : '0*$' >/dev/null
+                then
+                       # creating a new branch
+                       ;
+               else
+                       # updating -- make sure it is a fast forward
+                       mb=`git-merge-base "$2" "$3"`
+                       case "$mb,$2" in
+                        "$2,$mb")
+                               ;; # fast forward -- happy
+                       *)
+                               exit 1 ;; # unhappy
+                       esac
+               fi
+               ;;
+       *)
+               # No funny refs allowed
+               exit 1
+               ;;
+       esac
+
+       # Is the user allowed to update it?
+       me=`id -u -n` ;# e.g. "junio"
+       while read head_pattern users
+        do
+               if expr "$1" : "$head_pattern" >/dev/null
+               then
+                       case " $users " in
+                       *" $me "*)
+                               exit 0 ;; # happy
+                       ' * ')
+                               exit 0 ;; # anybody
+                       esac
+               fi
+       done
+       exit 1
+
+For the sake of simplicity, I assumed that you keep something
+like this in $GIT_DIR/info/allowed-pushers file:
+
+       refs/heads/master       junio
+        refs/heads/cogito$     pasky
+       refs/heads/bw/          linus
+        refs/heads/tmp/                *
+        refs/tags/v[0-9]*      junio
+
+With this, Linus can push or create "bw/penguin" or "bw/zebra"
+or "bw/panda" branches, Pasky can do only "cogito", and I can do
+master branch and make versioned tags.  And anybody can do
+tmp/blah branches.  This assumes all the users are in a single
+group that can write into $GIT_DIR/ and underneath.
+
+
+
+
+
+
+
+