1 From: Junio C Hamano <junkio@cox.net>
2 Subject: control access to branches.
3 Date: Thu, 17 Nov 2005 23:55:32 -0800
4 Message-ID: <7vfypumlu3.fsf@assigned-by-dhcp.cox.net>
5 Abstract: An example hooks/update script is presented to
6 implement repository maintenance policies, such as who can push
7 into which branch and who can make a tag.
9 When your developer runs git-push into the repository,
10 git-receive-pack is run (either locally or over ssh) as that
11 developer, so is hooks/update script. Quoting from the relevant
12 section of the documentation:
14 Before each ref is updated, if $GIT_DIR/hooks/update file exists
15 and executable, it is called with three parameters:
17 $GIT_DIR/hooks/update refname sha1-old sha1-new
19 The refname parameter is relative to $GIT_DIR; e.g. for the
20 master head this is "refs/heads/master". Two sha1 are the
21 object names for the refname before and after the update. Note
22 that the hook is called before the refname is updated, so either
23 sha1-old is 0{40} (meaning there is no such ref yet), or it
24 should match what is recorded in refname.
26 So if your policy is (1) always require fast-forward push
27 (i.e. never allow "git-push repo +branch:branch"), (2) you
28 have a list of users allowed to update each branch, and (3) you
29 do not let tags to be overwritten, then:
32 # This is a sample hooks/update script, written by JC
33 # in his e-mail buffer, so naturally it is not tested
34 # but hopefully would convey the idea.
39 # No overwriting an existing tag
40 if test -f "$GIT_DIR/$1"
46 # No rebasing or rewinding
47 if expr "$2" : '0*$' >/dev/null
49 # creating a new branch
52 # updating -- make sure it is a fast forward
53 mb=`git-merge-base "$2" "$3"`
56 ;; # fast forward -- happy
63 # No funny refs allowed
68 # Is the user allowed to update it?
69 me=`id -u -n` ;# e.g. "junio"
70 while read head_pattern users
72 if expr "$1" : "$head_pattern" >/dev/null
84 For the sake of simplicity, I assumed that you keep something
85 like this in $GIT_DIR/info/allowed-pushers file:
87 refs/heads/master junio
88 refs/heads/cogito$ pasky
91 refs/tags/v[0-9]* junio
93 With this, Linus can push or create "bw/penguin" or "bw/zebra"
94 or "bw/panda" branches, Pasky can do only "cogito", and I can do
95 master branch and make versioned tags. And anybody can do
96 tmp/blah branches. This assumes all the users are in a single
97 group that can write into $GIT_DIR/ and underneath.