diff options
Diffstat (limited to 'third_party/git/Documentation/howto/update-hook-example.txt')
-rw-r--r-- | third_party/git/Documentation/howto/update-hook-example.txt | 192 |
1 files changed, 0 insertions, 192 deletions
diff --git a/third_party/git/Documentation/howto/update-hook-example.txt b/third_party/git/Documentation/howto/update-hook-example.txt deleted file mode 100644 index 151ee84cebce..000000000000 --- a/third_party/git/Documentation/howto/update-hook-example.txt +++ /dev/null @@ -1,192 +0,0 @@ -From: Junio C Hamano <gitster@pobox.com> and Carl Baldwin <cnb@fc.hp.com> -Subject: control access to branches. -Date: Thu, 17 Nov 2005 23:55:32 -0800 -Message-ID: <7vfypumlu3.fsf@assigned-by-dhcp.cox.net> -Abstract: An example hooks/update script is presented to - implement repository maintenance policies, such as who can push - into which branch and who can make a tag. -Content-type: text/asciidoc - -How to use the update hook -========================== - -When your developer runs git-push into the repository, -git-receive-pack is run (either locally or over ssh) as that -developer, so is hooks/update script. Quoting from the relevant -section of the documentation: - - Before each ref is updated, if $GIT_DIR/hooks/update file exists - and executable, it is called with three parameters: - - $GIT_DIR/hooks/update refname sha1-old sha1-new - - The refname parameter is relative to $GIT_DIR; e.g. for the - master head this is "refs/heads/master". Two sha1 are the - object names for the refname before and after the update. Note - that the hook is called before the refname is updated, so either - sha1-old is 0{40} (meaning there is no such ref yet), or it - should match what is recorded in refname. - -So if your policy is (1) always require fast-forward push -(i.e. never allow "git-push repo +branch:branch"), (2) you -have a list of users allowed to update each branch, and (3) you -do not let tags to be overwritten, then you can use something -like this as your hooks/update script. - -[jc: editorial note. This is a much improved version by Carl -since I posted the original outline] - ----------------------------------------------------- -#!/bin/bash - -umask 002 - -# If you are having trouble with this access control hook script -# you can try setting this to true. It will tell you exactly -# why a user is being allowed/denied access. - -verbose=false - -# Default shell globbing messes things up downstream -GLOBIGNORE=* - -function grant { - $verbose && echo >&2 "-Grant- $1" - echo grant - exit 0 -} - -function deny { - $verbose && echo >&2 "-Deny- $1" - echo deny - exit 1 -} - -function info { - $verbose && echo >&2 "-Info- $1" -} - -# Implement generic branch and tag policies. -# - Tags should not be updated once created. -# - Branches should only be fast-forwarded unless their pattern starts with '+' -case "$1" in - refs/tags/*) - git rev-parse --verify -q "$1" && - deny >/dev/null "You can't overwrite an existing tag" - ;; - refs/heads/*) - # No rebasing or rewinding - if expr "$2" : '0*$' >/dev/null; then - info "The branch '$1' is new..." - else - # updating -- make sure it is a fast-forward - mb=$(git merge-base "$2" "$3") - case "$mb,$2" in - "$2,$mb") info "Update is fast-forward" ;; - *) noff=y; info "This is not a fast-forward update.";; - esac - fi - ;; - *) - deny >/dev/null \ - "Branch is not under refs/heads or refs/tags. What are you trying to do?" - ;; -esac - -# Implement per-branch controls based on username -allowed_users_file=$GIT_DIR/info/allowed-users -username=$(id -u -n) -info "The user is: '$username'" - -if test -f "$allowed_users_file" -then - rc=$(cat $allowed_users_file | grep -v '^#' | grep -v '^$' | - 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 - grant) grant >/dev/null "Granting access based on $allowed_users_file" ;; - deny) deny >/dev/null "Denying access based on $allowed_users_file" ;; - *) ;; - esac -fi - -allowed_groups_file=$GIT_DIR/info/allowed-groups -groups=$(id -G -n) -info "The user belongs to the following groups:" -info "'$groups'" - -if test -f "$allowed_groups_file" -then - rc=$(cat $allowed_groups_file | grep -v '^#' | grep -v '^$' | - 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 - done - deny "None of the user's groups are in the access list for this branch" - done - ) - case "$rc" in - grant) grant >/dev/null "Granting access based on $allowed_groups_file" ;; - deny) deny >/dev/null "Denying access based on $allowed_groups_file" ;; - *) ;; - esac -fi - -deny >/dev/null "There are no more rules to check. Denying access" ----------------------------------------------------- - -This uses two files, $GIT_DIR/info/allowed-users and -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/seen junio - refs/heads/cogito$ pasky - refs/heads/bw/.* linus - refs/heads/tmp/.* .* - refs/tags/v[0-9].* junio - -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 and "seen" branches and make versioned tags. And anybody -can do tmp/blah branches. The '+' sign at the "seen" record means -that JC can make non-fast-forward pushes on it. |