¿Cómo comparto un repositorio Git con múltiples usuarios en una máquina?

216

Tengo un repositorio de Git en un servidor de ensayo al que varios desarrolladores deben poder acceder. git-initparece tener una bandera muy cercana a lo que estoy buscando: --sharedexcepto que me gustaría que varias personas también accedan a ese repositorio. La bandera de git-clone's --sharedhace algo completamente diferente.

¿Cuál es la forma más fácil de cambiar los permisos de un repositorio existente?

Andrey Fedorov
fuente
Estoy usando "Github para Windows" y cambio entre dos cuentas de Github: stackoverflow.com/questions/18565876/…
Alisa

Respuestas:

186

Los permisos son una plaga.

Básicamente, debe asegurarse de que todos esos desarrolladores puedan escribir a todo en el repositorio de git.

Vaya a The New-Wave Solution para obtener el método superior de otorgar capacidad de escritura a un grupo de desarrolladores.

La solución estándar

Si coloca a todos los desarrolladores en un grupo creado especialmente, puede, en principio, simplemente hacer lo siguiente:

chgrp -R <whatever group> gitrepo
chmod -R g+swX gitrepo

Luego cambie el umaskpara que los usuarios 002lo hagan, de modo que se creen nuevos archivos con permisos de escritura grupal.

Los problemas con esto son legión; Si está en una distribución que asume una umaskde 022(como tener un usersgrupo común que incluye a todos por defecto), esto puede abrir problemas de seguridad en otros lugares. Y tarde o temprano, algo arruinará su esquema de permisos cuidadosamente diseñado, poniendo el repositorio fuera de acción hasta que obtenga rootacceso y lo arregle (es decir, vuelva a ejecutar los comandos anteriores).

La solución de la nueva ola

Una solución superior, aunque menos comprendida, y que requiere un poco más de soporte de sistema operativo / herramienta, es utilizar atributos extendidos POSIX. Solo he venido a esta área hace poco, así que mi conocimiento aquí no es tan bueno como podría ser. Pero, básicamente, una ACL extendida es la capacidad de establecer permisos en más que solo las 3 ranuras predeterminadas (usuario / grupo / otro).

Entonces, una vez más, crea tu grupo, luego ejecuta:

setfacl -R -m g:<whatever group>:rwX gitrepo
find gitrepo -type d | xargs setfacl -R -m d:g:<whatever group>:rwX

Esto configura la ACL extendida para el grupo para que los miembros del grupo puedan leer / escribir / acceder a cualquier archivo que ya esté allí (la primera línea); luego, también indique a todos los directorios existentes que los archivos nuevos deben tener esta misma ACL aplicada (la segunda línea).

Espero que te ponga en tu camino.

womble
fuente
62
git init tiene un parámetro llamado --shared que configura la variable core.sharedRepository para el trabajo en grupo. También puede establecer la variable en un repositorio existente. Eso elimina la necesidad de configurar manualmente umask como git lo establecerá en un valor razonable antes de manipular archivos.
ptman
66
+1 para los atributos extendidos de POSIX: ¡novedades para mí!
RobM
55
Cuando lo hice chmod -R g+swX, hizo que Git se sintiera muy infeliz y decidió que ya no era un repositorio de git ("repo no parece ser un repositorio de git"). Tuve que modificar todos los archivos . Para establecer el bit setgid en los directorios , intente find /path/to/repo -type d -print0 | xargs -0 chmod g+s. Todavía hago el chgrp -R thegroup /path/to/repo.
rescdsk
10
chmod -R g+swX gitrepoaplicará el bit setguid a los archivos, lo cual es un riesgo de seguridad. En su lugar, puede usarlo find . -type d -exec chmod g+s {} +para aplicarlo solo a directorios.
Ian Dunn
1
ACL (setfacl) no tiene configuración para setgid para imponer nuevos archivos y subdirectorios creados dentro de un directorio para heredar su ID de grupo. Por lo tanto, debe establecer setgid por separado a través de chmod. Sin embargo, la opción compartida de Git ( git-scm.com/docs/git-init ) le permite configurar gid y anular la máscara de usuario del usuario.
Chase T.
121

si creó el repositorio (o clonó un nuevo repositorio desnudo de uno existente) con

$ git init --shared=group 

o

$ git init --shared=0NNN

Se supone que Git maneja los permisos más allá de lo que proporciona su umask predeterminado. Por fin esto es cierto en mi versión de Git (1.6.3). Por supuesto, esto supone que sus usuarios están en el mismo grupo.

Sin embargo, si necesitara la administración de usuarios en múltiples grupos con diferentes grados de lectura / escritura, iría con gitosis. También he oído mencionar la gitolita ( http://github.com/sitaramc/gitolite ), una bifurcación de gitosis que se supone que proporciona permisos a nivel de sucursal, aunque no puedo decir que la haya usado personalmente.

Casa en la playa
fuente
99
Esta es definitivamente la respuesta correcta.
ELLIOTTCABLE
44
Tuve este problema y esta es, con mucho, la mejor respuesta. El único problema es que el --sharedargumento toma un octal, no hexadecimal. He confirmado esto en la fuente de Git 1.7.8 y el segundo ejemplo debería ser git init --shared=0NNN.
qpingu
3
¿Qué es la NNNmáscara de permisos o un número de grupo u otra cosa?
Craig McQueen
20
Por cierto, "grupo" arriba es una palabra clave, no un marcador de posición para el nombre de su grupo. Usted asigna el grupo usando el comando chgrp. Para un nuevo repositorio es git init --bare --shared=group myprojdonde myproj es su nombre de repositorio, seguido de chgrp -R mygroup myprojdonde mygroup es el nombre de su grupo.
labradort
2
Tenga en cuenta que si sus usuarios realizan confirmaciones cuando su grupo predeterminado es diferente de lo que debería ser, puede arruinar las cosas. Para solucionar este problema, necesitará que cada usuario transfiera cada archivo que posea en el repositorio al grupo correcto. Esto se repetirá a menos que descubra cómo hacer que todos creen / cambien nuevos archivos en / al grupo correcto antes de comprometerse y presionar.
ragerdl
55

Esto no se ha dicho, por lo que quiero agregarlo rápidamente.

Para asegurarse de que los problemas de permisos no recorten su cabeza fea, asegúrese de configurar lo siguiente en el archivo de configuración del repositorio compartido de git:

[core]
    sharedRepository = true

Esto asegurará que se respete la configuración de "umask" de su sistema.

Niels Joubert
fuente
66
De acuerdo con git-config (1) ( kernel.org/pub/software/scm/git/docs/git-config.html ) core.sharedRepository, debe establecer esto en "umask" o "false" para tener respeto git Umask del usuario.
David Schmitt
14
Esto y la respuesta de user35117 es correcta. Tenga en cuenta que "verdadero" es lo mismo que "grupo", y esto se puede configurar con el comando git config core.sharedRepository true.
ColinM
¿Todavía cambia la propiedad de un archivo cuando se empuja a remoto?
Duc Tran
2
Si desea configurar esto al clonar en lugar de después del hecho, el equivalente de git init --sharedes git clone --config core.sharedRepository=true. Es extraño usar git para --sharedsignificados tan diferentes en comandos tan similares.
stevek_mcc
21

El Manual del usuario de Git describe cómo compartir un repositorio de varias maneras.

Más complicadas, aunque las formas completas de compartir repositorios son:

Utilizamos GitHub para un equipo de 6 desarrolladores.

jtimberman
fuente
1
Me gusta la gitosis. Es una forma bastante efectiva de controlar el acceso basado en claves públicas.
Mike Mazur
¿Cómo resuelve alguna de estas soluciones el problema de "Me gustaría que varias personas accedan a ese repositorio"?
womble
Echa un vistazo a la gitosis. ese resuelve tu problema.
pilif
3
Cuando comparte el repositorio, las personas podrán extraerlo. Es probable que necesiten clonarlo o agregar una rama remota. La documentación que vinculé claramente lo guiará a través de la resolución de su problema; He utilizado todos los métodos descritos para ayudar a los desarrolladores a colaborar con el código fuente de Git. Que yo sepa, ServerFault no es para la retención.
jtimberman
3
Tengo que estar de acuerdo con el uso de gitosis. Evita el problema de los permisos mediante el uso de una sola cuenta autenticada por múltiples claves SSH. También se administra completamente a través de git commits.
Jeremy Bouse
9

También mire gitolite para alojar su repositorio git. Aparentemente, la gitosis ya no se está desarrollando.

mt3
fuente
4

Una forma de corregir los permisos en el repositorio compartido, para que los usuarios no tengan problemas de permisos al presionar, es crear un script de enlace posterior a la actualización que haga exactamente eso. Esto debería funcionar en cualquier versión de git.

Supongamos que tiene un repositorio compartido en /myrepo.git. Todos los archivos en ese repositorio pertenecen a decir mysharedgroup . Todos los usuarios que ingresan a ese repositorio también deben pertenecer a mysharedgroup . Ahora cree el siguiente archivo (cambiando mysharedgroup a sus preferencias):

/myrepo.git/hooks/post-update

#!/bin/sh
chmod -R g+w . 2>/dev/null
chgrp -R mysharedgroup . 2>/dev/null
bkmks
fuente
la respuesta correcta para cuando los usuarios tienen diferentes grupos predeterminados
Pat
Establecer el bit setgid en un directorio hará que los archivos que crean los usuarios hereden la misma propiedad del grupo que el directorio (si los usuarios pertenecen a ese grupo). Incluso si no es el grupo predeterminado de los usuarios. Entonces este gancho no es necesario. Esto es lo que hace la respuesta de @ womble (y mi comentario al respecto).
rescdsk
En mi máquina centos7, después de probar todas las soluciones enumeradas en esta página, una variante de la solución de @ bkmks anterior fue la única opción que realmente funcionó (configurando los ganchos posteriores a la fusión y posterior al pago en lugar de la actualización posterior como se indicó anteriormente).
Mike Godin
Creo que es un mal consejo promover una solución que canalice mensajes de error o advertencias en STDER /dev/null. Deje que el usuario vea primero estos mensajes y luego decida por sí mismo.
Daniel Böhmer
3

Para agregar los fragmentos de buenos consejos de las otras respuestas y comentarios sobre la configuración de un nuevo repositorio:

Si está configurando una marca nueva operación myrepoen /srv/gitel grupo mygroup, esto es lo que quiere:

mkdir /srv/git/myrepo.git
chgrp mygroup /srv/git/myrepo.git
git init --bare --shared /srv/git/myrepo.git
  1. la primera línea crea el directorio de repositorio
  2. la segunda línea establece su grupo en mygroup
  3. la tercera línea inicializa un repositorio simple con la siguiente configuración:
    1. core.bare = true: hazlo un repositorio desnudo
    2. core.sharedrepository = 1(igual que core.sharedrepository = group): el directorio repo y todos los directorios creados posteriormente en él serán administrados por git para permitir mygrouppermisos de lectura, escritura y ejecución (también con el bit sgid establecido) para trabajar con usuarios para quienes mygroupno es su grupo primario)
    3. receive.denyNonFastforwards = 1: denegar empujes no rápidos hacia el repositorio

Si desea ajustar los permisos de usuario, grupo u otros usuarios, use --shared=0NNN, donde NNNestán el usuario estándar, el grupo y otros bits para archivos (los bits de ejecución y sgid en los directorios serán administrados adecuadamente por git). Por ejemplo, esto permite el acceso de lectura y escritura al usuario, y el acceso de solo lectura al grupo (y sin acceso a otros):

git init --bare --shared=0640 /srv/git/myrepo.git

Esto permite el acceso de lectura y escritura al usuario y al grupo (y ningún acceso a otros):

git init --bare --shared=0660 /srv/git/myrepo.git

Esto permite el acceso de lectura y escritura al usuario y al grupo, y el acceso de solo lectura a otros:

git init --bare --shared=0664 /srv/git/myrepo.git

Tenga en cuenta que si no va a permitir el acceso de escritura al grupo, asegúrese de usar primero chownpara establecer el propietario del repositorio y luego ejecute el git initcomando como ese usuario (para asegurarse de que el repositorio se inicialice con el propietario correcto para todos los archivos iniciales y subdirectorios).

Justin Ludwig
fuente
Más correcto que las respuestas de mayor voto.
XO01
1

Hacer exactamente esto funcionó para mí, para un repositorio existente. Esto toma consejos de varias respuestas y comentarios antes:

Desde su directorio padre del repositorio, en el servidor:

chgrp -R <whatever group> gitrepo
chmod -R g+wX gitrepo
cd gitrepo
find . -type d -exec chmod g+s {} +
git config core.sharedRepository group
Luis de Arquer
fuente
0

La respuesta de @stevek_mcc es la que estaba buscando cuando busqué en Google esta pregunta

git clone --config core.sharedRepository=true
ragerdl
fuente