是否有可能有一个自定义.gitignore? 只读访问?

我在团队环境中工作,已经有一个.gitignore文件。

我想添加更多的项目.gitignore文件,但我不想检查这个文件。 可以设置只适用于我的自定义忽略文件吗?

另外,我想让别人只能读取我们服务器上的私有git存储库,如果我们将他们的SSH密钥添加到我们的服务器,他们将像其他人一样获得完整的访问权限。 我怎样才能限制它只读,不允许提交。

  1. 把你的私人的忽略规则放在.git/info/exclude 。 见gitignore(5)
  2. 对于只读访问,请使用git-daemon , Web服务器或Gitosis或Gitolite。

我知道我谈话有点迟,但是你可能要考虑使用

 git update-index --assume-unchanged [ FILE ] 

正如git帮助文档所述:

当“假设不变”位开启时, git停止检查工作树文件是否有可能的修改 ,所以当你改变工作树文件时,你需要手工取消设置该位以告诉git …

强调我的。 它继续说

这个选项可以被用作粗略的文件级机制来忽略被跟踪文件中未提交的改变 (类似于.gitignore对未跟踪文件所做的)。 如果需要在索引中修改这个文件,Git会失败(优雅地),例如,在提交时合并; 因此, 如果假设未跟踪的文件在上游发生更改,则需要手动处理该情况

所以请记住,您必须了解对这些文件所做的任何上游更改。

如果您想要再次开始跟踪文件,则只需使用即可

 git update-index --no-assume-unchange [ FILE ] 

我希望这有助于这个职位的任何未来的观众。

对于ssh部分,你应该考虑使用gitolite (替代gitosis)。

你可能会对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-usersallowed-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可以推动或创buildbw/penguinbw/zebrabw/panda分行,Pasky只能做cogito ,而JC可以做masterpu分行,并制作版本标签。 任何人都可以做tmp/blah分支。 pulogging中的“+”号表示JC可以使其非快速前进。

如果这个人还没有权限访问存储库所在的主机,也许这个人应该只有git-shell访问权限,而不是无限制的访问权限。 创build一个特殊用途的git用户,并在~git/.ssh/authorized_keys ,以下面的forms添加局外人的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 

根据您的本地设置,您可能需要将path调整为git-shell 。 请记住, sshd对于.ssh目录的权限是非常偏执的,所以closures它的组写位和下面的所有文件。

通过git用户来查看每个人意味着你需要能够区分别人,这就是myorg_git_user环境variables的目的。 而不是依靠无条件的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'" 

有了这个设置,只要有一个访问权限的朋友就可以用类似下面的命令克隆。 具体path将取决于您的设置。 为了使好的path工作,要么将你的仓库重定位到git用户的主目录,要么创build一个指向它的符号链接。

  $ git clone git@blankman.com.invalid:coolproject.git 

但将无法进行更新。

  $ git push origin mybranch 
总计0(delta 0),重用0(delta 0)
远程:错误:钩拒绝更新裁判/头/ mybranch
要git@blankman.com.invalid:coolproject.git
  !  [远程拒绝] mybranch  - > mybranch(钩拒绝)
错误:未能推动一些裁判'git@blankman.com.invalid:coolproject.git' 

你说你在团队环境中工作,所以我假设你的中央仓库是用--shared选项创build的。 (请参阅git config文档中的core.sharedRepository以及git init文档中的core.sharedRepository 。)确保新的git用户是系统组的成员,为您提供所有访问中央存储库的权限。

就像Fred Frodo说的那样,你可以把你的私有排除规则放在版本库的.git/info/exclude中。

如果要将相同的排除规则应用于计算机上的所有存储库,可以将以下内容添加到用户目录中的.gitconfig文件中。

 [core] excludesfile = /home/<myusername>/.gitexclude 

然后添加你的排除模式~/.gitexclude