Browse Source

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>
maint
Dmitry Potapov 17 years ago committed by Junio C Hamano
parent
commit
f9a08f618f
  1. 86
      Documentation/howto/update-hook-example.txt

86
Documentation/howto/update-hook-example.txt

@ -65,7 +65,7 @@ function info { @@ -65,7 +65,7 @@ function info {

# Implement generic branch and tag policies.
# - 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
refs/tags/*)
git rev-parse --verify -q "$1" &&
@ -80,7 +80,7 @@ case "$1" in @@ -80,7 +80,7 @@ case "$1" in
mb=$(git-merge-base "$2" "$3")
case "$mb,$2" in
"$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
fi
;;
@ -95,21 +95,30 @@ allowed_users_file=$GIT_DIR/info/allowed-users @@ -95,21 +95,30 @@ allowed_users_file=$GIT_DIR/info/allowed-users
username=$(id -u -n)
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 '^$' |
while read head_pattern user_patterns; do
matchlen=$(expr "$1" : "$head_pattern")
if [ "$matchlen" == "${#1}" ]; then
info "Found matching head pattern: '$head_pattern'"
for user_pattern in $user_patterns; do
info "Checking user: '$username' against pattern: '$user_pattern'"
matchlen=$(expr "$username" : "$user_pattern")
if [ "$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"
fi
while read heads user_patterns
do
# does this rule apply to us?
head_pattern=${heads#+}
matchlen=$(expr "$1" : "${head_pattern#+}")
test "$matchlen" = ${#1} || continue

# if non-ff, $heads must be with the '+' prefix
test -n "$noff" &&
test "$head_pattern" = "$heads" && continue

info "Found matching head pattern: '$head_pattern'"
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
)
case "$rc" in
@ -124,23 +133,32 @@ groups=$(id -G -n) @@ -124,23 +133,32 @@ groups=$(id -G -n)
info "The user belongs to the following 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 '^$' |
while read head_pattern group_patterns; do
matchlen=$(expr "$1" : "$head_pattern")
if [ "$matchlen" == "${#1}" ]; then
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 [ "$matchlen" == "${#groupname}" ]; then
grant "Allowing group: '$groupname' with pattern: '$group_pattern'"
fi
done
while read heads group_patterns
do
# does this rule apply to us?
head_pattern=${heads#+}
matchlen=$(expr "$1" : "${head_pattern#+}")
test "$matchlen" = ${#1} || continue

# if non-ff, $heads must be with the '+' prefix
test -n "$noff" &&
test "$head_pattern" = "$heads" && continue

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
deny "None of the user's groups are in the access list for this branch"
fi
done
deny "None of the user's groups are in the access list for this branch"
done
)
case "$rc" in
@ -159,6 +177,7 @@ allowed-groups, to describe which heads can be pushed into by @@ -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:

refs/heads/master junio
+refs/heads/pu junio
refs/heads/cogito$ pasky
refs/heads/bw/.* linus
refs/heads/tmp/.* .*
@ -166,7 +185,8 @@ whom. The format of each file would look like this: @@ -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"
or "bw/panda" branches, Pasky can do only "cogito", and JC can
do master branch and make versioned tags. And anybody can do
tmp/blah branches.
do master and pu branches and make versioned tags. And anybody
can do tmp/blah branches. The '+' sign at the pu record means
that JC can make non-fast-forward pushes on it.

------------

Loading…
Cancel
Save