사용자 지정 .gitignore를 가질 수 있습니까? 읽기 전용 액세스?
팀 환경에서 작업하고 있으며 이미 .gitignore
파일이 있습니다.
.gitignore
파일에 항목을 더 추가 하고 싶지만이 파일도 확인하고 싶지 않습니다. 나에게만 적용되는 사용자 정의 무시 파일을 설정할 수 있습니까?
또한 누군가에게 우리 서버의 비공개 git 저장소에 대한 읽기 전용 액세스 권한을 부여하고 싶습니다. SSH 키를 서버에 추가하면 다른 모든 사람과 마찬가지로 전체 액세스 권한을 갖게됩니다. 커밋을 허용하지 않고 읽기 전용으로 제한하려면 어떻게해야합니까?
- 비공개 무시 규칙을
.git/info/exclude
. 을 참조하십시오gitignore(5)
. - 읽기 전용 액세스의 경우
git-daemon
, 웹 서버 또는 Gitosis 또는 Gitolite를 사용합니다.
대화에 조금 늦었지만 사용을 고려할 수도 있습니다.
git update-index --assume-unchanged [ FILE ]
git 도움말 문서에 따르면 다음과 같습니다.
"assume unchanged"비트가 켜져 있으면 git은 작업 트리 파일에서 가능한 수정 확인을 중지하므로 작업 트리 파일을 변경할 때 git에 알리려면 비트를 수동으로 설정 해제해야합니다.
내 강조. 계속해서
이 옵션은 ... 추적 된 파일에서 커밋되지 않은 변경 사항을 무시하는 대략적인 파일 수준 메커니즘으로 사용할 수 있습니다 ( 추적되지 않은 파일 에 대해 .gitignore가 수행하는 작업과 유사). Git은 예를 들어 커밋에서 병합 할 때 색인에서이 파일을 수정해야하는 경우 (정상적으로) 실패합니다. 따라서 추적되지 않은 것으로 가정 된 파일이 업스트림으로 변경되는 경우 상황을 수동으로 처리해야합니다 .
따라서 이러한 파일에 대한 업스트림 변경 사항을 알고 있어야합니다.
파일 추적을 다시 시작하려면 다음을 사용하기 만하면됩니다.
git update-index --no-assume-unchange [ FILE ]
이 게시물의 향후 시청자에게 도움이되기를 바랍니다.
ssh 부분의 경우 Gitolite (gitosis의 대체) 사용을 고려해야 합니다.
Fred Frodo가 말했듯 .git/info/exclude
이 저장소 에 비공개 제외 규칙을 넣을 수 있습니다 .
시스템의 모든 저장소에 동일한 제외 규칙을 적용하려면 .gitconfig
사용자 디렉토리 의 파일에 다음을 추가 할 수 있습니다 .
[core]
excludesfile = /home/<myusername>/.gitexclude
그런 다음 제외 패턴을 ~/.gitexclude
.
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"
With this hook in place, you then give particular users or groups to make changes to the repository. Anyone else who can see it has read-only access.
This uses two files,
$GIT_DIR/info/allowed-users
andallowed-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/.* .* refs/tags/v[0-9].* junio
With this, Linus can push or create
bw/penguin
orbw/zebra
orbw/panda
branches, Pasky can do onlycogito
, and JC can domaster
andpu
branches and make versioned tags. And anybody can dotmp/blah
branches. The '+' sign at thepu
record means that JC can make non-fast-forward pushes on it.
If this person doesn't already have access to the host where your repository lives, maybe that person should have only git-shell
access rather than unrestricted access. Create a special-purpose git user and in ~git/.ssh/authorized_keys
, add the outsider's SSH key in the following form. Note that the key should be on one long line, but I've wrapped it below to aid presentation.
no-agent-forwarding,no-port-forwarding,no-pty,no-X11-forwarding, command="env myorg_git_user=joeuser /usr/local/bin/git-shell -c \"${SSH_ORIGINAL_COMMAND:-}\"" ssh-rsa AAAAB3...2iQ== joeuser@foo.invalid
Depending on your local setup, you may need to adjust the path to git-shell
. Remember that sshd
is highly paranoid about permissions of the .ssh
directory, so turn off its group-write bits and all files beneath it.
Funneling everyone through the git user means you need to be able tell people apart, and this is the purpose of the myorg_git_user
environment variable. Instead of relying on an unconditional username=$(id -u -n)
, tweak your update hook to use it:
# 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'"
With this setup, your friend with readonly access will clone with a command resembling the one below. The particular path will depend on your setup. To make the nice path work, either relocate your repository to the git user's home directory or create a symlink that points to it.
$ git clone git@blankman.com.invalid:coolproject.git
but won't be able to make updates.
$ git push origin mybranch Total 0 (delta 0), reused 0 (delta 0) remote: error: hook declined to update refs/heads/mybranch To git@blankman.com.invalid:coolproject.git ! [remote rejected] mybranch -> mybranch (hook declined) error: failed to push some refs to 'git@blankman.com.invalid:coolproject.git'
You said you're working in a team environment, so I assume your central repository was created with the --shared
option. (See core.sharedRepository
in the git config
documentation and --shared
in the git init
documentation.) Make sure the new git user is a member of the system group that gives all of you access to your central repository.
'Program Tip' 카테고리의 다른 글
Ruby에서 세미콜론을 사용할 수 있습니까? (0) | 2020.10.29 |
---|---|
mongodb에서 자식 개체를 쿼리하는 방법 (0) | 2020.10.29 |
매개 변수를 받아들이는 expressjs 미들웨어 만들기 (0) | 2020.10.29 |
실행중인 Docker 컨테이너에서 파일 및 stdout을 읽는 방법 (0) | 2020.10.29 |
C에서 데이터 유형의 최소 및 최대 값 (0) | 2020.10.29 |