2011-05-24 122 views
60

我在團隊環境中工作,並且已經有一個.gitignore文件。是否有可能有一個自定義.gitignore?只讀訪問?

我想添加更多的項目到.gitignore文件,但我不想檢查這個文件。可以設置只適用於我的自定義忽略文件嗎?如果我們將SSH密鑰添加到我們的服務器,他們將像其他人一樣獲得完全訪問權限。我怎樣才能將其限制爲只讀,不允許提交。

+0

可能重複[我可以創建一個特定於用戶的gitignore文件嗎?](https://stackoverflow.com/questions/5724455/can-i-make-a-user-specific-gitignore-file) – 2017-11-07 15:31:57

回答

91
  1. 把你的私人忽略規則放在.git/info/exclude。見gitignore(5)
  2. 對於只讀訪問,請使用git-daemonweb server或Gitosis或Gitolite。
+0

並使情況更糟糕,我想這個gitignore是爲一個特定的項目,而不是全局設置。 – Blankman 2011-05-24 21:44:21

+7

@Blankman:將它放在項目根目錄下的'.git/info/exclude' *中*。 – 2011-05-24 21:45:15

+1

使其完成:使用配置選項'core.excludesfile',您可以指定_global_排除文件。 – KingCrunch 2011-05-24 21:47:04

2

對於ssh部分,您應該考慮使用Gitolite(替代gitosis)。

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-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能做的只有​​,和JC可以做masterpu分支機構,使版本標籤。任何人都可以做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== [email protected]

根據您當地的設置,您可能需要將路徑調整爲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 [email protected]:coolproject.git

但將無法進行更新。

$ git push origin mybranch 
Total 0 (delta 0), reused 0 (delta 0) 
remote: error: hook declined to update refs/heads/mybranch 
To [email protected]:coolproject.git 
! [remote rejected] mybranch -> mybranch (hook declined) 
error: failed to push some refs to '[email protected]:coolproject.git'

你說你在團隊環境中工作,所以我想你的中央存儲庫是用--shared選項創建。 (請參閱core.sharedRepository中的git config documentation--shared,git init documentation。)確保新的git用戶是系統組的成員,它爲您提供了所有對中央存儲庫的訪問權限。

15

我知道我有點晚了交談,但你可能要考慮使用

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

由於git的幫助文件規定:

當「假設不變」位上,git停止檢查工作樹文件的可能的修改,所以你需要手動取消設置該位,告訴GIT當你改變工作樹文件...

強調我的。它接着說

此選項可... 用作粗文件級機制忽略跟蹤的文件提交的更改(類似於什麼的.gitignore確實爲未跟蹤文件)。如果需要在索引中修改這個文件,Git將失敗(優雅地)合併時提交;因此,如果假設未跟蹤文件在上游發生更改,則需要手動處理該情況

所以,請記住,您將不得不意識到對這些文件所做的任何上游更改。

在要開始跟蹤該文件的事件再次所有你需要做的就是使用

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

我希望這可以幫助任何未來的這個帖子的觀衆。

0

就像Fred Frodo說的那樣,您可以將您的私人排除規則放入存儲庫的.git/info/exclude中。

如果要將相同的排除規則應用於計算機上的所有存儲庫,可以將以下內容添加到用戶目錄中的.gitconfig文件中。

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

然後將您的排除模式添加到~/.gitexclude

相關問題