update-hook-example: optionally allow non-fast-forward
Sometimes it is desirable to have non-fast-forward branches in a shared repository. A typical example of that is the 'pu' branch. This patch extends the format of allowed-users and allow-groups files by using the '+' sign at the beginning as the mark that non-fast-forward pushes are permitted to the branch. Signed-off-by: Dmitry Potapov <dpotapov@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Dmitry Potapov committed
Jun 26, 2008 at 03:14 UTC
f9a08f618f3aa586a6859283dd2d0cd5a8dc4f96
1 file changed
+53
-33
Documentation/howto/update-hook-example.txt
+53
-33
@@ -65,7 +65,7 @@ function info {
65
66
# Implement generic branch and tag policies.
67
# - Tags should not be updated once created.
68
-# - Branches should only be fast-forwarded.
68
+# - Branches should only be fast-forwarded unless their pattern starts with '+'
69
case "$1" in
70
refs/tags/*)
71
git rev-parse --verify -q "$1" &&
@@ -80,7 +80,7 @@ case "$1" in
80
mb=$(git-merge-base "$2" "$3")
81
case "$mb,$2" in
82
"$2,$mb") info "Update is fast-forward" ;;
83
- *) deny >/dev/null "This is not a fast-forward update." ;;
83
+ *) noff=y; info "This is not a fast-forward update.";;
84
esac
85
fi
86
;;
@@ -95,21 +95,30 @@ allowed_users_file=$GIT_DIR/info/allowed-users
95
username=$(id -u -n)
96
info "The user is: '$username'"
97
98
-if [ -f "$allowed_users_file" ]; then
98
+if test -f "$allowed_users_file"
99
+then
100
rc=$(cat $allowed_users_file | grep -v '^#' | grep -v '^$' |
100
- while read head_pattern user_patterns; do
101
- matchlen=$(expr "$1" : "$head_pattern")
102
- if [ "$matchlen" == "${#1}" ]; then
103
- info "Found matching head pattern: '$head_pattern'"
104
- for user_pattern in $user_patterns; do
105
- info "Checking user: '$username' against pattern: '$user_pattern'"
106
- matchlen=$(expr "$username" : "$user_pattern")
107
- if [ "$matchlen" == "${#username}" ]; then
108
- grant "Allowing user: '$username' with pattern: '$user_pattern'"
109
- fi
110
- done
111
- deny "The user is not in the access list for this branch"
112
- fi
101
+ while read heads user_patterns
102
+ do
103
+ # does this rule apply to us?
104
+ head_pattern=${heads#+}
105
+ matchlen=$(expr "$1" : "${head_pattern#+}")
106
+ test "$matchlen" = ${#1} || continue
107
+
108
+ # if non-ff, $heads must be with the '+' prefix
109
+ test -n "$noff" &&
110
+ test "$head_pattern" = "$heads" && continue
111
+
112
+ info "Found matching head pattern: '$head_pattern'"
113
+ for user_pattern in $user_patterns; do
114
+ info "Checking user: '$username' against pattern: '$user_pattern'"
115
+ matchlen=$(expr "$username" : "$user_pattern")
116
+ if test "$matchlen" = "${#username}"
117
+ then
118
+ grant "Allowing user: '$username' with pattern: '$user_pattern'"
119
+ fi
120
+ done
121
+ deny "The user is not in the access list for this branch"
122
done
123
)
124
case "$rc" in
@@ -124,23 +133,32 @@ groups=$(id -G -n)
133
info "The user belongs to the following groups:"
134
info "'$groups'"
135
127
-if [ -f "$allowed_groups_file" ]; then
136
+if test -f "$allowed_groups_file"
137
+then
138
rc=$(cat $allowed_groups_file | grep -v '^#' | grep -v '^$' |
129
- while read head_pattern group_patterns; do
130
- matchlen=$(expr "$1" : "$head_pattern")
131
- if [ "$matchlen" == "${#1}" ]; then
132
- info "Found matching head pattern: '$head_pattern'"
133
- for group_pattern in $group_patterns; do
134
- for groupname in $groups; do
135
- info "Checking group: '$groupname' against pattern: '$group_pattern'"
136
- matchlen=$(expr "$groupname" : "$group_pattern")
137
- if [ "$matchlen" == "${#groupname}" ]; then
138
- grant "Allowing group: '$groupname' with pattern: '$group_pattern'"
139
- fi
140
- done
139
+ while read heads group_patterns
140
+ do
141
+ # does this rule apply to us?
142
+ head_pattern=${heads#+}
143
+ matchlen=$(expr "$1" : "${head_pattern#+}")
144
+ test "$matchlen" = ${#1} || continue
145
+
146
+ # if non-ff, $heads must be with the '+' prefix
147
+ test -n "$noff" &&
148
+ test "$head_pattern" = "$heads" && continue
149
+
150
+ info "Found matching head pattern: '$head_pattern'"
151
+ for group_pattern in $group_patterns; do
152
+ for groupname in $groups; do
153
+ info "Checking group: '$groupname' against pattern: '$group_pattern'"
154
+ matchlen=$(expr "$groupname" : "$group_pattern")
155
+ if test "$matchlen" = "${#groupname}"
156
+ then
157
+ grant "Allowing group: '$groupname' with pattern: '$group_pattern'"
158
+ fi
159
done
142
- deny "None of the user's groups are in the access list for this branch"
143
- fi
160
+ done
161
+ deny "None of the user's groups are in the access list for this branch"
162
done
163
)
164
case "$rc" in
@@ -159,6 +177,7 @@ allowed-groups, to describe which heads can be pushed into by
177
whom. The format of each file would look like this:
178
179
refs/heads/master junio
180
+ +refs/heads/pu junio
181
refs/heads/cogito$ pasky
182
refs/heads/bw/.* linus
183
refs/heads/tmp/.* .*
@@ -166,7 +185,8 @@ whom. The format of each file would look like this:
185
186
With this, Linus can push or create "bw/penguin" or "bw/zebra"
187
or "bw/panda" branches, Pasky can do only "cogito", and JC can
169
-do master branch and make versioned tags. And anybody can do
170
-tmp/blah branches.
188
+do master and pu branches and make versioned tags. And anybody
189
+can do tmp/blah branches. The '+' sign at the pu record means
190
+that JC can make non-fast-forward pushes on it.
191
192
------------