我在团队环境中工作,并且已经存在.gitignore
个文件。
我想在.gitignore
文件中添加更多项目,但我不想在其中检查此文件。可以设置仅适用于我的自定义忽略文件吗?
此外,我想在我们的服务器上给某人只读访问私有git存储库,如果我将他们的SSH密钥添加到我们的服务器,他们将像其他人一样获得完全访问权限。如何将其限制为只读,不允许提交。
答案 0 :(得分:110)
.git/info/exclude
中。见gitignore(5)
。git-daemon
,web server或Gitosis或Gitolite。答案 1 :(得分:18)
我知道我的谈话有点迟,但你可能想考虑使用
git update-index --assume-unchanged [ FILE ]
正如git帮助文档所述:
当“假设未更改”位置位时, git停止检查工作树文件是否可能进行修改,因此您需要手动取消设置该位以在更改工作树文件时告诉git。 ..
强调我的。它继续说
此选项可以... 用作粗略的文件级机制来忽略跟踪文件中未提交的更改(类似于.gitignore对未跟踪文件的操作)。如果需要在索引中修改此文件,Git将失败(优雅地),例如合并时提交;因此,如果在上游更改了假定未跟踪文件,则需要手动处理该情况。
所以请记住,您必须了解对这些文件所做的任何上游更改。
如果您想再次开始跟踪文件,您只需使用
即可git update-index --no-assume-unchange [ FILE ]
我希望这有助于此帖子的未来观众。
答案 2 :(得分:2)
对于ssh部分,你应该考虑使用Gitolite(替代gitosis)。
答案 3 :(得分:1)
像Fred Frodo所说,您可以将私有排除规则放在存储库的.git/info/exclude
中。
如果要将相同的排除规则应用于计算机上的所有存储库,可以将以下内容添加到用户目录中的.gitconfig
文件中。
[core]
excludesfile = /home/<myusername>/.gitexclude
然后将您的排除模式添加到~/.gitexclude
。
答案 4 :(得分:0)
你可能对Junio写的update hook和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
有了这个,Linus可以推送或创建
bw/penguin
或bw/zebra
或bw/panda
个分支,Pasky只能cogito
,JC可以执行master
和pu
分支并制作版本化标签。任何人都可以做tmp/blah
个分支机构。pu
记录上的“+”符号表示JC可以对其进行非快进推送。
如果此人无法访问您的存储库所在的主机,则该人员可能只有git-shell
访问权限而不是不受限制的访问权限。创建一个专用的git用户,在~git/.ssh/authorized_keys
中,以下面的形式添加局外人的SSH密钥。请注意,密钥应该在一个长行上,但我已将其包装在下面以帮助演示。
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
根据您的本地设置,您可能需要调整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 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'
您说您在团队环境中工作,因此我假设您的中央存储库是使用--shared
选项创建的。 (请参阅git config
documentation中的core.sharedRepository
和git init
documentation中的--shared
。)确保新git用户是系统组的成员,让您可以访问所有人中央存储库。