Git compromete acceso a parte de un repository

Digamos que tengo un repository con dos directorys, high_level / y low_level /. Tengo un queueborador que quiere acceso de confirmación, pero solo me siento cómodo (y solo quieren) dejándolos tocar el directory high_level /.

Sería demasiado inconveniente tener que correr para revertir commits locos.

¿Es posible hacer esto sin dividir el repository?

Es posible hacer esto con un gancho de pre-recepción, pero no tiene nada incorporado.

Para hacerlo en un gancho de pre-recepción, haga que su gancho explore las actualizaciones de tags propuestas, por ejemplo:

#! /bin/sh ... while read oldsha newsha fullref; do verify $oldsha $newsha $fullref || { echo "$fullref: $oldsha -> $newsha update rejected" exit 1 } done 

Aún debe escribir la function verify ():

 NULL_SHA1=0000000000000000000000000000000000000000 # 40 0's reftype() { case $1 in $NULL_SHA1) echo none;; *) git cat-file -t $1;; } verify() { local oldsha=$1 newsha=$2 fullref=$3 local otype=$(reftype $oldsha) ntype=$(reftype $newsha) local update_type case $otype,$ntype in none,*) update_type=create;; *,none) update_type=delete;; *,*) update_type=update;; esac # now if update_type is create or delete, check permissions # but if update_type is update, check revisions verify_$update_type $oldsha $newsha $fullref } 

(Lo anterior puede ser más elegante, por ejemplo, puede verificar la creación / eliminación de tags anotadas, y puede verificar el tipo de reference frente al tipo de object).

Esta "verificación" simplemente devuelve lo que devuelve el correspondiente más específico verify_create, verify_delete o verify_update. Entonces tienes que escribir esos:

 verify_create() { local oldsha=$1 newsha=$2 fullref=$3 # only $USER = wilma is allowed to create [ "$USER" = wilma ] && return 0 echo "you ($USER) are not allowed to create things" return 1 } verify_delete() { local oldsha=$1 newsha=$2 fullref=$3 # only $USER = fnetworking is allowed to delete [ "$USER" = fnetworking ] && return 0 echo "you ($USER) are not allowed to delete things" return 1 } 

Ahora estamos abajo para verify_update:

 verify_update() { local oldsha=$1 newsha=$2 fullref=$3 local shortref rev case "$fullref" in refs/heads/*) # a branch shortref=${fullref#refs/heads/} ;; *) # everything else - only barney is allowed to do those # (and we don't check any further) [ "$USER" = barney ] && return 0 echo "you ($USER) are not allowed to modify $fullref" return 1 ;; esac # user betty is restricted on branches that do not start with betty* # everyone else is unrestricted [ "$USER" = betty ] || return 0 case "$shortref" in betty*) return 0;; esac # 1. betty is NOT allowed to REMOVE commits, even with force-push if [ $(git rev-list --count $newsha..$oldsha) -ne 0 ]; then echo "commit to branch $shortref would remove some revs" return 1 fi # 2. betty is not allowed to make certain changes # eg, first we forbid merges: if [ $(git rev-list --count --min-parents=2 \ $oldsha..$newsha) -ne 0 ]; then echo "you ($USER) are not allowed to push a merge" return 1 fi # then we look at each commit for rev in $(git rev-list $oldsha..$newsha); do check_betty_commit $rev "$shortref" || return 1 done } 

Vaya, ya casi llegamos. Solo necesita verificar los cambios que betty propone:

 check_betty_commit() { local rev=$1 shortref="$2" # unfortunately, pipe to a loop causes the loop to # run in a sub-shell, so it's a bit complicated here. git diff-tree -r --no-renames --name-only --no-commit-id $rev | (retval=0; while read pathname; do case "$pathname" in forbidden/path/*) echo "branch $shortref: $rev modifies $pathname" retval=1 ;; esac done exit $retval) || return 1 } 

Nota: la mayoría de los anteriores no se han probado.

La encoding de los nombres de usuario también probablemente no es buena. Pero esto debería darte algunas ideas sobre cómo guiar esto, si realmente quieres ir por este path.

Por cierto, hay un script diferente (pero más probado) aquí que implementa un set limitado de controles de acceso por usuario basados ​​en la configuration en el repository en sí, en lugar de codificarlos.

No estoy al tanto de ninguna forma de hacerlo fuera de la caja. Probablemente puedas escribir un script de gancho para hacerlo en el repository principal, pero parece que la forma correcta de hacerlo es no permitir que este queueborador se comprometa con el repository.

En cambio, haga que se comprometan con su propio repository, luego puede colocar los que desee en el repository principal. De esta forma, usted tiene control total sobre cómo y cuándo sus compromisos entran en su repository (o no, si no cumplen con sus estándares).

Si realmente necesita esta funcionalidad, la function "submodule" @SLaks sugerida puede satisfacer sus necesidades; esencialmente puede tratar el "high_level" como un proyecto separado que asigna a su repository "low_level". Luego puede comprometerse con el repository high_level, y puede get esos commits en su repository low_level. Ver http://git-scm.com/book/es/Git-Tools-Submodules