Junio가 작성하고 Carl이 개선 한 업데이트 후크에 관심이있을 수 있습니다 . 아래 코드를에 배치 $GIT_DIR/hooks/update
하고 chmod +x
.
#!/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"
이 후크를 사용하면 특정 사용자 또는 그룹에 저장소를 변경할 수 있습니다. 이를 볼 수있는 다른 사람은 읽기 전용 액세스 권한이 있습니다.
이 두 개의 파일을 사용 $GIT_DIR/info/allowed-users
하고 allowed-groups
머리가 누구에 의해로 밀어 수있는 설명하기 위해. 각 파일의 형식은 다음과 같습니다.
refs/heads/master junio
+refs/heads/pu junio
refs/heads/cogito$ pasky
refs/heads/bw/.* linus
refs/heads/tmp/.* .*
refs/tags/v[0-9].* junio
이와 함께, 리누스는 밀거나 만들 수 있습니다 bw/penguin
또는 bw/zebra
또는 bw/panda
지점, Pasky 만 할 수있는 cogito
, 그리고 JC 수행 할 수 있습니다 master
및 pu
지점 및 버전 태그를합니다. 누구든지 tmp/blah
가지를 할 수 있습니다. pu
레코드 의 '+'기호는 JC가 비 빨리 감기 푸시를 수행 할 수 있음을 의미합니다.
이 사람이 저장소가있는 호스트에 대한 액세스 권한이없는 경우 해당 사용자는 git-shell
무제한 액세스가 아닌 액세스 권한 만 가져야 합니다. 특수 목적의 git 사용자를 만들고에서 ~git/.ssh/authorized_keys
외부인의 SSH 키를 다음 형식으로 추가합니다. 키는 하나의 긴 줄에 있어야하지만 프레젠테이션을 돕기 위해 아래에 줄 바꿈했습니다.
에이전트 포워딩 없음, 포트 포워딩 없음, pty 없음, X11 포워딩 없음,
command = "env myorg_git_user = joeuser / usr / local / bin / git-shell -c
\ "$ {SSH_ORIGINAL_COMMAND :-} \" "ssh-rsa AAAAB3 ... 2iQ == joeuser@foo.invalid
로컬 설정에 따라 경로를로 조정해야 할 수 있습니다 git-shell
. 그 기억 sshd
의 권한에 대한 높은 편집증 .ssh
때문에 아래의 그룹 - 쓰기 비트와 모든 파일을 해제 디렉토리.
git 사용자를 통해 모든 사람을 안내한다는 것은 사람들을 구분할 수 있어야한다는 것을 의미하며, 이것이 myorg_git_user
환경 변수 의 목적입니다 . 무조건에 의존하는 대신 username=$(id -u -n)
업데이트 후크를 조정하여 사용하십시오.
# Implement per-branch controls based on username
allowed_users_file=$GIT_DIR/info/allowed-users
if [ -z "$myorg_git_user" ]; then
username=$(id -u -n)
else
username=$myorg_git_user
fi
info "The user is: '$username'"
이 설정을 사용하면 읽기 전용 액세스 권한이있는 친구가 아래 명령과 유사한 명령으로 복제됩니다. 특정 경로는 설정에 따라 다릅니다. 멋진 경로가 작동하도록하려면 저장소를 git 사용자의 홈 디렉토리로 재배치하거나이를 가리키는 심볼릭 링크를 만듭니다.
$ git clone git@blankman.com.invalid : coolproject.git
하지만 업데이트 할 수 없습니다.
$ git push origin mybranch
총 0 (델타 0), 재사용 0 (델타 0)
원격 : 오류 : 후크가 refs / heads / mybranch 업데이트를 거부했습니다.
git@blankman.com.invalid : coolproject.git로
! [원격 거부 됨] mybranch-> mybranch (후크 거부 됨)
오류 : 일부 참조를 'git@blankman.com.invalid : coolproject.git'로 푸시하지 못했습니다.
팀 환경에서 작업한다고 하셨으므로 중앙 저장소가 --shared
옵션 으로 생성되었다고 가정합니다 . (참조 core.sharedRepository
에서 git config
문서 및 --shared
에서 git init
문서 .) 확인 새로운 자식 사용자가 여러분 모두가 중앙 저장소에 액세스 할 수 있습니다 시스템 그룹의 구성원인지 확인하십시오.