是否可以使用自定义.gitignore?只读访问权限?


79

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

我想向.gitignore文件中添加更多项目,但是我不想在任何一个中检查该文件。可以设置仅适用于我的自定义忽略文件?

另外,我想授予某人对我们服务器上私有git存储库的只读访问权限,如果我将他们的SSH密钥添加到我们的服务器中,他们将像其他所有人一样获得完全访问权限。如何将其限制为只读,不允许提交。


Answers:


122
  1. 将您的私人忽略规则放入.git/info/exclude。请参阅gitignore(5)
  2. 对于只读访问,使用git-daemon,一个web服务器,或者Gitosis的,或Gitolite。

更糟糕的是,我希望此gitignore用于特定项目,而不是全局设置。
Blankman

7
@Blankman:将其放在.git/info/exclude 项目的根目录中
弗雷德·福

1
使其完整:使用config选项,core.excludesfile您可以指定全局排除文件。
KingCrunch

1
对于任何新安装,我都同意Simon的观点,您应该使用乙醇钠而不是gitosis。
ebneter 2011年

1
一种有用的使用方式:首先->ln -s .git/info/exclude .personalGitignore然后我们可以添加# ln -s .git/info/exclude .personalGitignore \n .personalGitignore到.gitignore
JosuGoñi18年

18

我知道我的谈话时间有些晚,但是您可能要考虑使用

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

如git help文档所述:

当“假定未更改”位打开时,git停止检查工作树文件以进行可能的修改,因此您需要手动取消设置该位,以在更改工作树文件时告诉git ...

强调我的。继续说

此选项可以用作粗略的文件级机制,以忽略跟踪文件中未提交的更改(类似于.gitignore对未跟踪文件所做的操作)。如果需要修改索引中的该文件(例如合并提交)时,Git将失败(正常)。因此,如果假定未跟踪的文件在上游被更改,则您将需要手动处理这种情况

因此,请记住,您将必须知道对这些文件所做的任何上游更改。

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

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

希望对以后的读者有帮助。



2

就像Fred Frodo所说的那样,您可以将私有排除规则放在.git/info/exclude存储库的中。

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

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

然后将排除模式添加到中~/.gitexclude


1

您可能对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

有了这个,莱纳斯可以推动或创造bw/penguinbw/zebrabw/panda分支机构,Pasky只能做cogito,和JC可以做masterpu树枝,使版本标签。任何人都可以做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)
远程:错误:挂钩拒绝更新参考/头/ mybranch
到git@blankman.com.invalid:coolproject.git
 ![远程拒绝] mybranch-> mybranch(挂钩被拒绝)
错误:无法将一些引用推送到'git@blankman.com.invalid:coolproject.git'

您说您在团队环境中工作,所以我假设您的中央存储库是使用--shared选项创建的。(见core.sharedRepository的在git config文档--sharedgit init文档。)确保新的git用户,让大家访问你的中央资料库系统组的成员。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.