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>
This commit is contained in:
Dmitry Potapov 2008-06-26 03:14:31 +04:00 committed by Junio C Hamano
parent 41e98de428
commit f9a08f618f

View File

@ -65,7 +65,7 @@ function info {
# Implement generic branch and tag policies. # Implement generic branch and tag policies.
# - Tags should not be updated once created. # - Tags should not be updated once created.
# - Branches should only be fast-forwarded. # - Branches should only be fast-forwarded unless their pattern starts with '+'
case "$1" in case "$1" in
refs/tags/*) refs/tags/*)
git rev-parse --verify -q "$1" && git rev-parse --verify -q "$1" &&
@ -80,7 +80,7 @@ case "$1" in
mb=$(git-merge-base "$2" "$3") mb=$(git-merge-base "$2" "$3")
case "$mb,$2" in case "$mb,$2" in
"$2,$mb") info "Update is fast-forward" ;; "$2,$mb") info "Update is fast-forward" ;;
*) deny >/dev/null "This is not a fast-forward update." ;; *) noff=y; info "This is not a fast-forward update.";;
esac esac
fi fi
;; ;;
@ -95,21 +95,30 @@ allowed_users_file=$GIT_DIR/info/allowed-users
username=$(id -u -n) username=$(id -u -n)
info "The user is: '$username'" info "The user is: '$username'"
if [ -f "$allowed_users_file" ]; then if test -f "$allowed_users_file"
then
rc=$(cat $allowed_users_file | grep -v '^#' | grep -v '^$' | rc=$(cat $allowed_users_file | grep -v '^#' | grep -v '^$' |
while read head_pattern user_patterns; do while read heads user_patterns
matchlen=$(expr "$1" : "$head_pattern") do
if [ "$matchlen" == "${#1}" ]; then # does this rule apply to us?
info "Found matching head pattern: '$head_pattern'" head_pattern=${heads#+}
for user_pattern in $user_patterns; do matchlen=$(expr "$1" : "${head_pattern#+}")
info "Checking user: '$username' against pattern: '$user_pattern'" test "$matchlen" = ${#1} || continue
matchlen=$(expr "$username" : "$user_pattern")
if [ "$matchlen" == "${#username}" ]; then # if non-ff, $heads must be with the '+' prefix
grant "Allowing user: '$username' with pattern: '$user_pattern'" test -n "$noff" &&
fi test "$head_pattern" = "$heads" && continue
done
deny "The user is not in the access list for this branch" info "Found matching head pattern: '$head_pattern'"
fi for user_pattern in $user_patterns; do
info "Checking user: '$username' against pattern: '$user_pattern'"
matchlen=$(expr "$username" : "$user_pattern")
if test "$matchlen" = "${#username}"
then
grant "Allowing user: '$username' with pattern: '$user_pattern'"
fi
done
deny "The user is not in the access list for this branch"
done done
) )
case "$rc" in case "$rc" in
@ -124,23 +133,32 @@ groups=$(id -G -n)
info "The user belongs to the following groups:" info "The user belongs to the following groups:"
info "'$groups'" info "'$groups'"
if [ -f "$allowed_groups_file" ]; then if test -f "$allowed_groups_file"
then
rc=$(cat $allowed_groups_file | grep -v '^#' | grep -v '^$' | rc=$(cat $allowed_groups_file | grep -v '^#' | grep -v '^$' |
while read head_pattern group_patterns; do while read heads group_patterns
matchlen=$(expr "$1" : "$head_pattern") do
if [ "$matchlen" == "${#1}" ]; then # does this rule apply to us?
info "Found matching head pattern: '$head_pattern'" head_pattern=${heads#+}
for group_pattern in $group_patterns; do matchlen=$(expr "$1" : "${head_pattern#+}")
for groupname in $groups; do test "$matchlen" = ${#1} || continue
info "Checking group: '$groupname' against pattern: '$group_pattern'"
matchlen=$(expr "$groupname" : "$group_pattern") # if non-ff, $heads must be with the '+' prefix
if [ "$matchlen" == "${#groupname}" ]; then test -n "$noff" &&
grant "Allowing group: '$groupname' with pattern: '$group_pattern'" test "$head_pattern" = "$heads" && continue
fi
done info "Found matching head pattern: '$head_pattern'"
for group_pattern in $group_patterns; do
for groupname in $groups; do
info "Checking group: '$groupname' against pattern: '$group_pattern'"
matchlen=$(expr "$groupname" : "$group_pattern")
if test "$matchlen" = "${#groupname}"
then
grant "Allowing group: '$groupname' with pattern: '$group_pattern'"
fi
done done
deny "None of the user's groups are in the access list for this branch" done
fi deny "None of the user's groups are in the access list for this branch"
done done
) )
case "$rc" in case "$rc" in
@ -159,6 +177,7 @@ allowed-groups, to describe which heads can be pushed into by
whom. The format of each file would look like this: whom. The format of each file would look like this:
refs/heads/master junio refs/heads/master junio
+refs/heads/pu junio
refs/heads/cogito$ pasky refs/heads/cogito$ pasky
refs/heads/bw/.* linus refs/heads/bw/.* linus
refs/heads/tmp/.* .* refs/heads/tmp/.* .*
@ -166,7 +185,8 @@ whom. The format of each file would look like this:
With this, Linus can push or create "bw/penguin" or "bw/zebra" With this, Linus can push or create "bw/penguin" or "bw/zebra"
or "bw/panda" branches, Pasky can do only "cogito", and JC can or "bw/panda" branches, Pasky can do only "cogito", and JC can
do master branch and make versioned tags. And anybody can do do master and pu branches and make versioned tags. And anybody
tmp/blah branches. can do tmp/blah branches. The '+' sign at the pu record means
that JC can make non-fast-forward pushes on it.
------------ ------------