3 # gitolite VREF to count votes before allowing pushes to certain branches.
5 # This approximates gerrit's voting (but it is SHA based; I believe Gerrit is
6 # more "changeset" based). Here's how it works:
8 # - A normal developer "bob" proposes changes to master by pushing a commit to
9 # "pers/bob/master", then informs the voting members by email.
11 # - Some or all of the voting members fetch and examine the commit. If they
12 # approve, they "vote" for the commit like so. For example, say voting
13 # member "alice" fetched bob's proposed commit into "bob-master" on her
14 # clone, then tested or reviewed it. She would approve it by running:
15 # git push origin bob-master:votes/alice/master
17 # - Once enough votes have been tallied (hopefully there is normal team
18 # communication that says "hey I approved your commit", or it can be checked
19 # by 'git ls-remote origin' anyway), Bob, or any developer, can push the
20 # same commit (same SHA) to master and the push will succeed.
22 # - Finally, a "trusted" developer can push a commit to master without
23 # worrying about the voting restriction at all.
25 # The config for this example would look like this:
28 # # allow personal branches (to submit proposed changes)
29 # RW+ pers/USER/ = @devs
32 # # allow only voters to vote
33 # RW+ votes/USER/ = @voters
36 # # normal access rules go here; should allow *someone* to push master
39 # # 2 votes required to push master, but trusted devs don't have this restriction
40 # RW+ VREF/VOTES/2/master = @trusted-devs
41 # - VREF/VOTES/2/master = @devs
43 # Note: "2 votes required to push master" means at least 2 refs matching
44 # "votes/*/master" have the same SHA as the one currently being pushed.
46 # ----------------------------------------------------------------------
48 # see gitolite docs for what the first 7 arguments mean
51 # arg-8 is a number; see below
52 # arg-9 is a simple branch name (i.e., "master", etc). Currently this code
53 # does NOT do vote counting for branch names with more than one component
60 die
() { echo "$@" >&2; exit 1; }
61 [ -z "$8" ] && die
"not meant to be run manually"
69 # nothing to do if the branch being pushed is not "master" (using our example)
70 [ "$ref" = "refs/heads/$branch" ] ||
exit 0
72 # find how many votes have come in
73 votes
=`git for-each-ref refs/heads/votes/*/$branch | grep -c $newsha`
75 # send back a vref if we don't have the minimum votes needed. For trusted
76 # developers this will invoke the RW+ rule and pass anyway, but for others it
77 # will invoke the "-" rule and fail.
78 [ $votes -ge $votes_needed ] ||
echo $refex "require at least $votes_needed votes to push $branch"