可以有一个自定义的.gitignore吗?只读访问?

可以有一个自定义的.gitignore吗?只读访问?,git,gitignore,Git,Gitignore,我在团队环境中工作,已经有一个.gitignore文件 我想向.gitignore文件添加更多项目,但我也不想签入此文件。是否可以设置仅适用于我的自定义忽略文件 另外,我想让某人以只读方式访问服务器上的私有git存储库,如果我将他们的SSH密钥添加到服务器上,他们将像其他人一样获得完全访问权限。如何将其限制为只读,不允许提交 将您的私人忽略规则放入.git/info/exclude。看 对于只读访问,请使用、a或Gitosis或Gitolite 对于SSH部分,你应该考虑使用(替换GITISA)

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

我想向
.gitignore
文件添加更多项目,但我也不想签入此文件。是否可以设置仅适用于我的自定义忽略文件

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

  • 将您的私人忽略规则放入
    .git/info/exclude
    。看
  • 对于只读访问,请使用、a或Gitosis或Gitolite

  • 对于SSH部分,你应该考虑使用(替换GITISA)。

    < P>你可能对儒尼奥写的一篇文章感兴趣,并且卡尔改进了。将下面的代码放在
    $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可以对其进行非快进推送

    如果此人还没有访问存储库所在主机的权限,那么此人应该只有
    gitshell
    访问权限,而不是不受限制的访问权限。创建一个特殊用途的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用户的主目录,或者创建指向它的符号链接

    $ git clone git@blankman.com.invalid:coolproject.git $git克隆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' $git推送源mybranch 总计0(增量0),重复使用0(增量0) 远程:错误:钩子拒绝更新refs/heads/mybranch 到git@blankman.com.invalid:coolproject.git ! [远程拒绝]mybranch->mybranch(钩子拒绝) 错误:无法将某些引用推送到'git@blankman.com.invalid:coolproject.git'
    您说过您在团队环境中工作,所以我假设您的中央存储库是使用
    --shared
    选项创建的。(请参阅<代码>核心.SyrDyDeStase<代码> >共享< <代码> >中,确保新Git用户是系统组的成员,让所有人访问您的中央存储库。

    < P>我知道我有点晚了,但您可能想考虑使用

    git update-index --assume-unchanged [ FILE ]
    
    正如git帮助文档所述:

    当“假定未更改”位处于启用状态时,git将停止检查工作树文件是否存在可能的修改,因此您需要手动取消设置该位,以便在更改工作树文件时通知git

    我的。它接着说

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

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

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

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

    我希望这能帮助这篇文章的未来读者。

    就像Fred Frodo说的,你可以将你的私有排除规则放在存储库的
    .git/info/exclude

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

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

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

    ,更糟糕的是,我希望这个gitignore用于特定的项目,不是全局设置。@Blankman:将其放入项目根目录的
    .git/info/exclude
    中。完成:使用配置选项
    core.excludesfile
    可以指定全局排除文件。对于任何新安装,我同意Simon的意见,你应该使用gitolite而不是gitosis。一个有用的方法是:首先->
    ln-s.git/info/exclude.personalGitignore
    ,然后我们可以将
    \ln-s.git/info/exclude.personalGitignore\n.personalGitignore
    添加到.gitIgnore的可能重复项
    [core]       
        excludesfile = /home/<myusername>/.gitexclude