Comment partager un référentiel Git avec plusieurs utilisateurs sur une machine?

216

J'ai un référentiel Git sur un serveur de transfert que plusieurs développeurs doivent pouvoir exploiter. git-initsemble avoir un drapeau très proche de ce que je recherche:, --sharedsauf que j'aimerais que plusieurs personnes se rendent dans ce référentiel également. Le git-clone« s --shareddrapeau fait quelque chose de tout à fait différent.

Quel est le moyen le plus simple de modifier les autorisations d'un référentiel existant?

Andreï Fedorov
la source
J'utilise "Github pour Windows" et permute entre deux comptes Github: stackoverflow.com/questions/18565876/…
Alisa

Réponses:

186

Les autorisations sont un ravageur.

En gros, vous devez vous assurer que tous ces développeurs peuvent écrire dans tout le référentiel git.

Passez à la solution New-Wave pour la méthode supérieure d’octroi de capacités d’écriture à un groupe de développeurs.

La solution standard

Si vous placez tous les développeurs dans un groupe spécialement créé, vous pouvez en principe simplement:

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

Modifiez ensuite le paramètre umaskpour les utilisateurs 002afin que les nouveaux fichiers soient créés avec des autorisations accessibles en écriture au groupe.

Les problèmes avec ceci sont légion; Si vous êtes sur une distribution qui suppose un umaskde 022(comme avoir un usersgroupe commun qui inclut tout le monde par défaut), cela peut créer des problèmes de sécurité ailleurs. Et tôt ou tard, quelque chose va bousiller votre système de permissions soigneusement conçu, mettant le référentiel hors d’action jusqu’à ce que vous obteniez un rootaccès et le corrigiez (c’est-à-dire, relancez les commandes ci-dessus).

La solution New-Wave

Une solution supérieure - bien que moins bien comprise et nécessitant un peu plus de prise en charge des systèmes d’exploitation / des outils - consiste à utiliser les attributs étendus POSIX. Je ne suis venu dans cette région que récemment, donc mes connaissances ne sont pas aussi intéressantes que possible. Mais fondamentalement, une liste de contrôle d'accès étendue permet de définir des autorisations sur plus de 3 emplacements par défaut (utilisateur / groupe / autre).

Alors encore une fois, créez votre groupe, puis lancez:

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

Cela configure la liste de contrôle d'accès étendue pour le groupe afin que les membres du groupe puissent lire / écrire / accéder aux fichiers déjà présents (la première ligne); Ensuite, indiquez également à tous les répertoires existants que la même liste de contrôle d'accès doit être appliquée aux nouveaux fichiers (la deuxième ligne).

J'espère que cela vous amène sur votre chemin.

femme
la source
62
git init a un paramètre appelé --shared qui définit la variable core.sharedRepository pour le travail en groupe. Vous pouvez également définir la variable sur un référentiel existant. Cela supprime la nécessité de définir manuellement umask car git le définira à une valeur raisonnable avant de manipuler des fichiers.
ptman
6
+1 pour les attributs étendus POSIX - une nouvelle pour moi!
RobM
5
Lorsque je l’ai fait chmod -R g+swX, cela a rendu Git très malheureux et il a décidé que ce n’était plus un référentiel git ("repo ne semble pas être un référentiel git"). Je devais vérifier tous les fichiers . Pour définir simplement le bit setgid sur les répertoires , essayez find /path/to/repo -type d -print0 | xargs -0 chmod g+s. Toujours faire le chgrp -R thegroup /path/to/repo.
rescdsk
10
chmod -R g+swX gitrepoappliquera le bit setguid aux fichiers, ce qui constitue un risque pour la sécurité. Au lieu de cela, vous pouvez utiliser find . -type d -exec chmod g+s {} +pour l'appliquer uniquement aux répertoires.
Ian Dunn le
1
ACL (setfacl) ne dispose pas du paramètre setgid pour appliquer les nouveaux fichiers et sous-répertoires créés dans un répertoire afin d'hériter de son ID de groupe. Par conséquent, vous devez définir setgid séparément via chmod. L'option --shared de git ( git-scm.com/docs/git-init ) vous permet toutefois de définir un identifiant et de remplacer le umask de l'utilisateur.
Chase T.
121

si vous avez créé le référentiel (ou cloné un nouveau référentiel nu sur un référentiel existant) avec

$ git init --shared=group 

ou

$ git init --shared=0NNN

Git est supposé gérer les autorisations au-delà de ce que votre umask par défaut fournit. Enfin, cela est vrai sur ma version de Git (1.6.3). Bien entendu, cela suppose que vos utilisateurs appartiennent au même groupe.

Si j'avais besoin de gérer des utilisateurs dans plusieurs groupes avec des degrés variables de lecture / écriture, je choisirais la gitose. J'ai aussi entendu parler de gitolite ( http://github.com/sitaramc/gitolite ), un fork de gitosis qui est supposé fournir des autorisations au niveau de la branche, mais je ne peux pas dire que je l'ai tous personnellement utilisé.

Maison de plage
la source
9
C'est vraiment la bonne réponse.
ELLIOTTCABLE
4
J'ai eu ce problème et c'est de loin la meilleure réponse. Le seul problème est que l' --sharedargument prend une valeur octale, pas hexadécimale. Je l'ai confirmé dans la source de Git 1.7.8 et le deuxième exemple devrait l'être git init --shared=0NNN.
Qpingu
3
Qu'est- NNNce que le masque de permission, un numéro de groupe ou autre chose?
Craig McQueen
20
BTW, "groupe" ci-dessus est un mot clé, pas un espace réservé pour le nom de votre groupe. Vous affectez le groupe à l'aide de la commande chgrp. Pour un nouveau git init --bare --shared=group myprojréférentiel, il s'agit de myproj, le nom de votre référentiel, suivi de celui chgrp -R mygroup myprojoù mygroup est votre nom de groupe.
labradort
2
Sachez que si vos utilisateurs effectuent des validations lorsque leur groupe par défaut est différent de ce qu'il devrait être, cela peut tout gâcher. Pour résoudre ce problème, vous aurez besoin que chaque utilisateur chgrp chaque fichier qu'il possède dans le référentiel vers le bon groupe. Cela se reproduira à moins que vous ne trouviez le moyen de faire en sorte que tout le monde crée / modifie de nouveaux fichiers dans / vers le bon groupe avant de valider et de pousser.
Ragerdl
55

Cela n'a pas été dit, je veux donc l'ajouter rapidement.

Pour vous assurer que les problèmes d'autorisations ne coupent pas leur tête laide, assurez-vous de définir les éléments suivants dans le fichier de configuration de votre référentiel partagé git:

[core]
    sharedRepository = true

Cela garantira que les paramètres "umask" de votre système sont respectés.

Niels Joubert
la source
6
Selon git-config (1) ( kernel.org/pub/software/scm/git/docs/git-config.html ) core.sharedRepository, vous devez définir ceci sur "umask" ou "false" pour que git soit respecté. umask de l'utilisateur.
David Schmitt
14
Ceci et la réponse de user35117 est correcte. Notez que "true" est identique à "group" et peut être défini à l'aide de la commande git config core.sharedRepository true.
ColinM
Est-ce que cela change toujours la propriété d'un fichier quand il est poussé à distance?
Duc Tran
2
Si vous souhaitez configurer cela lors du clonage plutôt qu'après, l’équivalent de git init --sharedest git clone --config core.sharedRepository=true. Etrange de git à utiliser --sharedpour des significations si différentes dans des commandes similaires.
stevek_mcc
21

Le manuel de l'utilisateur Git explique comment partager un référentiel de plusieurs manières.

Les moyens les plus complexes de partage de référentiels, bien que comportant de nombreuses fonctionnalités, sont les suivants:

Nous utilisons GitHub pour une équipe de 6 développeurs.

jtimberman
la source
1
J'aime la gitose. C'est un moyen assez efficace de contrôler l'accès en fonction des clés publiques.
Mike Mazur
Comment l'une de ces solutions résout-elle le problème de "J'aimerais que plusieurs personnes accèdent à ce référentiel"?
womble
regardez la gitose. celui-là résout votre problème.
pilif
3
Lorsque vous partagez le référentiel, les utilisateurs pourront en tirer. Ils devront probablement le cloner ou ajouter une branche distante. La documentation que j'ai liée vous guidera très clairement dans la résolution de votre problème; J'ai utilisé toutes les méthodes décrites pour aider les développeurs à collaborer avec du code source avec Git. À ma connaissance, ServerFault n'est pas destiné à une prise en main.
jtimberman
3
Je suis d'accord avec l'utilisation de la gitose. Il résout le problème des autorisations en utilisant un seul compte authentifié par plusieurs clés SSH. Il est également entièrement géré via git commits.
Jeremy Bouse
9

Consultez également gitolite pour l'hébergement de votre référentiel git. La gitose n'est apparemment plus en train de se développer.

mt3
la source
4

Un moyen de corriger les autorisations dans le référentiel partagé, afin d'éviter les problèmes d'autorisations lors de l'insertion, consiste à créer un script de hook post-mise à jour qui le fera exactement. Cela devrait fonctionner dans n'importe quelle version de Git.

Supposons que vous ayez un référentiel partagé dans /myrepo.git. Tous les fichiers de ce dépôt appartiennent à mysharedgroup . Tous les utilisateurs poussant vers ce référentiel doivent également appartenir à mysharedgroup . Créez maintenant le fichier suivant (en modifiant mysharedgroup selon vos préférences):

/myrepo.git/hooks/post-update

#!/bin/sh
chmod -R g+w . 2>/dev/null
chgrp -R mysharedgroup . 2>/dev/null
bkmks
la source
la bonne réponse lorsque les utilisateurs ont des groupes par défaut différents
Pat
Si vous définissez le bit setgid sur un répertoire, les fichiers créés par les utilisateurs hériteront de la même propriété de groupe que le répertoire (si les utilisateurs appartiennent à ce groupe). Même si ce n'est pas le groupe par défaut des utilisateurs. Alors ce crochet n'est pas nécessaire. C’est ce que la réponse de @ womble (et mon commentaire à ce sujet) fait.
rescdsk
Sur ma machine centos7, après avoir essayé toutes les solutions répertoriées sur cette page, une variante de la solution @ bkmks ci-dessus était la seule option qui fonctionnait réellement (définition des points d'ancrage post-fusion et post-paiement au lieu de post-mise à jour comme ci-dessus).
Mike Godin
Je pense que c’est un mauvais conseil de promouvoir une solution qui envoie des messages d’erreur ou des avertissements sur STDER /dev/null. S'il vous plaît laissez l'utilisateur voir ces messages d'abord et ensuite décider de leur propre chef.
Daniel Böhmer
3

Pour regrouper les éléments de bon conseil des différentes autres réponses et commentaires sur la mise en place d'un nouveau référentiel:

Si vous configurez un nouveau repo myrepodans /srv/gitle groupe mygroup, c'est ce que vous voulez:

mkdir /srv/git/myrepo.git
chgrp mygroup /srv/git/myrepo.git
git init --bare --shared /srv/git/myrepo.git
  1. la première ligne crée le répertoire repo
  2. la deuxième ligne définit son groupe à mygroup
  3. la troisième ligne initialise un rapport nu avec la configuration suivante:
    1. core.bare = true: en faire un repo nu
    2. core.sharedrepository = 1(identique à core.sharedrepository = group): le répertoire repo et tous les répertoires créés ultérieurement y seront gérés par git pour permettre les autorisations de mygrouplecture, d’écriture et d’exécution (avec le bit sgid également défini - de manière à fonctionner avec des utilisateurs pour lesquels ils mygroupne sont pas les leurs. groupe primaire)
    3. receive.denyNonFastforwards = 1: refuser les poussées non rapides vers le repo

Si vous souhaitez ajuster avec précision les autorisations des utilisateurs, des groupes ou des autres utilisateurs, utilisez l' --shared=0NNNemplacement où se NNNtrouvent l'utilisateur, le groupe et les autres bits standard des fichiers (les bits execute et sgid des répertoires seront gérés de manière appropriée par git). Par exemple, cela permet un accès en lecture et en écriture à l'utilisateur, ainsi qu'un accès en lecture seule au groupe (et aucun accès aux autres):

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

Cela permet un accès en lecture et en écriture à l'utilisateur et au groupe (et aucun accès aux autres):

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

Cela permet un accès en lecture et en écriture à l'utilisateur et au groupe, ainsi qu'un accès en lecture seule à d'autres:

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

Notez que si vous n'autorisez pas l'accès en écriture au groupe, assurez-vous d'abord chownde définir le propriétaire du référentiel, puis exécutez la git initcommande en tant qu'utilisateur (pour vous assurer que le référentiel est initialisé avec le propriétaire correct tous les fichiers et sous-répertoires initiaux).

Justin Ludwig
la source
Plus correct que les réponses de vote plus élevées.
XO01
1

Faire exactement cela a fonctionné pour moi, pour un référentiel existant. Cela prend conseil de plusieurs réponses et commentaires avant:

À partir du répertoire parent de votre référentiel, sur le serveur:

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
la source
0

@stevek_mcc la réponse est celle que je cherchais quand j'ai cherché sur Google pour cette question

git clone --config core.sharedRepository=true
ragerdl
la source