2011-05-24 18 views
60

Estoy trabajando en un entorno de equipo, y ya existe un archivo .gitignore.¿Es posible tener un .gitignore personalizado? ¿Acceso de solo lectura?

Quiero agregar más elementos al archivo .gitignore, pero no quiero verificar este archivo tampoco. Es posible establecer archivos de ignorar personalizados que solo se aplican a mí?

Además, quiero dar a alguien que lea solo acceso a un repositorio privado de git en nuestro servidor, si agrego su clave SSH a nuestro servidor obtendrán acceso completo como todos los demás. ¿Cómo puedo limitarlo a solo lectura, sin commits permitidos?

+0

Posible duplicado de [¿Puedo hacer un archivo de gitignore específico del usuario?] (https://stackoverflow.com/questions/5724455/can-i-make-a-user-specific-gitignore-file) –

Respuesta

91
  1. Ponga sus reglas privadas de ignorar en .git/info/exclude. Ver gitignore(5).
  2. Para acceso de solo lectura, use git-daemon, web server o Gitosis o Gitolite.
+0

y para empeorar las cosas, quiero que este gitignore sea para un proyecto específico, no un configuración global. – Blankman

+7

@Blankman: póngalo en '.git/info/exclude' * en el directorio raíz del proyecto *. –

+1

The make it complete: con la opción de configuración 'core.excludesfile' puede especificar un archivo _global_ excludes. – KingCrunch

2

Para la parte ssh, debe considerar el uso de Gitolite (un reemplazo para la gitosis).

0

Puede que le interese un update hook que Junio ​​escribió y que mejoró Carl. Coloque el código a continuación en $GIT_DIR/hooks/update y no olvide habilitarlo con 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" 

Con este enganche en su lugar, le permite a determinados usuarios o grupos realizar cambios en el repositorio. Cualquier otra persona que pueda verlo tiene acceso de solo lectura.

Este utiliza dos archivos, $GIT_DIR/info/allowed-users y allowed-groups, para describir que se dirige puede ser empujado a por quién. El formato de cada archivo se vería así:

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 

Con esto, Linus puede empujar o crear bw/penguin o bw/zebra o bw/panda ramas, Pasky sólo puede hacer cogito, y JC puede hacer master y pu ramas y hacer etiquetas versionados . Y cualquiera puede hacer tmp/blah ramas. El signo '+' en el registro pu significa que JC puede realizar impulsos no rápidos hacia adelante.

Si esta persona no tiene ya acceso al host donde vive su repositorio, tal vez esa persona debe tener solamente git-shell acceso en lugar de un acceso sin restricciones. Cree un usuario de git de propósito especial y en ~git/.ssh/authorized_keys, agregue la clave SSH del externo de la siguiente forma. Tenga en cuenta que la clave debe estar en una línea larga, pero la he incluido a continuación para ayudar a la presentación.

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]

Dependiendo de su configuración local, es posible que tenga que ajustar la ruta de acceso a git-shell. Recuerde que sshd es altamente paranoico con respecto a los permisos del directorio .ssh, por lo que debe desactivar sus bits de escritura de grupo y todos los archivos debajo de él.

Canalizar a todos a través del usuario git significa que necesita poder distinguir a las personas, y este es el propósito de la variable de entorno myorg_git_user.En lugar de confiar en una incondicional username=$(id -u -n), ajustar su gancho de actualización para usarlo:

# 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'" 

Con esta configuración, su amigo con acceso de sólo lectura será clonar con un comando parecido a la de abajo. La ruta particular dependerá de su configuración. Para que la buena ruta funcione, reubique su repositorio en el directorio de inicio del usuario de git o cree un enlace simbólico que lo señale.

$ git clone [email protected]:coolproject.git

pero no podrá realizar actualizaciones.

$ 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'

Usted dijo que está trabajando en un ambiente de equipo, así que supongo que su repositorio central fue creado con la opción --shared. (Consulte core.sharedRepository en git config documentation y --shared en el git init documentation). Asegúrese de que el nuevo usuario de git sea miembro del grupo de sistemas que le da acceso a todos a su repositorio central.

15

Yo sé que soy un poco tarde a la conversación, pero es posible que desee considerar el uso de

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

como el documento git ayudar a los estados:

Cuando el "asumen sin cambios" bit está activado , git deja de verificar los archivos de árbol de trabajo para posibles modificaciones, por lo que debe desarmar manualmente el bit para indicar a git cuando cambie el archivo de árbol de trabajo ...

Énfasis mío. Se llega a decir

Esta opción puede ser ... utilizado como un mecanismo a nivel de archivo grueso para ignorar los cambios no confirmados en los archivos de orugas (similar a lo que hace .gitignore para archivos sin seguimiento). Git fallará (correctamente) en caso de que necesite modificar este archivo en el índice, p. cuando se fusiona en un compromiso; por lo tanto, en caso de que el archivo asumido no rastreado se cambie en sentido ascendente, deberá manejar la situación manualmente.

Por lo tanto, tenga en cuenta que deberá tener en cuenta cualquier cambio en la cadena ascendente de estos archivos.

En el caso de que desea iniciar el seguimiento del archivo de nuevo todo lo que tiene que hacer es usar

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

espero que esto ayude a cualquier espectadores futuras de este post.

0

Como dijo Fred Frodo, puede poner sus reglas de exclusión privada en el .git/info/exclude del repositorio.

Si desea aplicar las mismas reglas de exclusión a todos los repositorios en su máquina, puede agregar lo siguiente al archivo .gitconfig en su directorio de usuario.

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

Publique sus patrones excluye a ~/.gitexclude.

Cuestiones relacionadas