사용자 지정 .gitignore를 가질 수 있습니까? 읽기 전용 액세스?


79

팀 환경에서 작업하고 있으며 이미 .gitignore파일이 있습니다.

.gitignore파일에 항목을 더 추가 하고 싶지만이 파일도 확인하고 싶지 않습니다. 나에게만 적용되는 사용자 지정 무시 파일을 설정할 수 있습니까?

또한 누군가에게 우리 서버의 개인 git 저장소에 대한 읽기 전용 액세스 권한을 부여하고 싶습니다. SSH 키를 서버에 추가하면 다른 모든 사람과 마찬가지로 전체 액세스 권한을 갖게됩니다. 커밋이 허용되지 않고 읽기 전용으로 제한하려면 어떻게해야합니까?


답변:


122
  1. 비공개 무시 규칙을 .git/info/exclude. 을 참조하십시오 gitignore(5).
  2. 읽기 전용 액세스의 경우 git-daemon, 웹 서버 , Gitosis 또는 Gitolite를 사용합니다.

설상가상으로 저는이 gitignore가 글로벌 설정이 아닌 특정 프로젝트를위한 것이기를 원합니다.
Blankman

7
@Blankman : .git/info/exclude 프로젝트의 루트 디렉토리에 넣으십시오 .
Fred Foo

1
완료 : config 옵션 core.excludesfile을 사용하여 전역 제외 파일을 지정할 수 있습니다 .
KingCrunch

1
새로 설치하는 경우 Simon의 의견에 동의합니다. gitosis보다는 gitolite를 사용해야합니다.
ebneter

1
이것을 사용하는 유용한 방법 : 먼저-> ln -s .git/info/exclude .personalGitignore그런 다음 # ln -s .git/info/exclude .personalGitignore \n .personalGitignore.gitignore에 추가 할 수 있습니다
Josu Goñi

18

대화에 조금 늦었다는 것을 알고 있지만

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

git 도움말 문서에 따르면 다음과 같습니다.

"assume unchanged"비트가 켜져 있으면 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-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

이와 함께, 리누스는 밀거나 만들 수 있습니다 bw/penguin또는 bw/zebra또는 bw/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)
원격 : 오류 : 후크가 refs / heads / mybranch 업데이트를 거부했습니다.
git@blankman.com.invalid : coolproject.git로
 ! [원격 거부 됨] mybranch-> mybranch (후크 거부 됨)
오류 : 일부 참조를 'git@blankman.com.invalid : coolproject.git'로 푸시하지 못했습니다.

팀 환경에서 작업한다고 하셨으므로 중앙 저장소가 --shared옵션 으로 생성되었다고 가정합니다 . (참조 core.sharedRepository에서 git config문서--shared에서 git init문서 .) 확인 새로운 자식 사용자가 여러분 모두가 중앙 저장소에 액세스 할 수 있습니다 시스템 그룹의 구성원인지 확인하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.