Come posso condividere un repository Git con più utenti su una macchina?


216

Ho un repository Git su un server di gestione temporanea a cui più sviluppatori devono poter attingere. git-initsembra avere una bandiera molto vicina a quello che sto cercando:, --sharedtranne che vorrei che più persone attirassero anche quel repository. La git-clone's --sharedbandiera fa qualcosa di completamente diverso.

Qual è il modo più semplice per modificare le autorizzazioni di un repository esistente?


Sto usando "Github per Windows" e cambio tra due account Github: stackoverflow.com/questions/18565876/…
Alisa,

Risposte:


186

Le autorizzazioni sono un parassita.

Fondamentalmente, è necessario assicurarsi che tutti quegli sviluppatori possano scrivere su tutto nel repository git.

Passa a The New-Wave Solution per il metodo superiore di concessione di capacità di scrittura a un gruppo di sviluppatori.

La soluzione standard

Se metti tutti gli sviluppatori in un gruppo appositamente creato, in linea di principio puoi semplicemente:

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

Quindi modificare il umaskper gli utenti in 002, in modo che i nuovi file vengano creati con autorizzazioni scrivibili in gruppo.

I problemi con questo sono legione; se siete su una distro che assume una umaskdi 022(come quello di avere un comune usersgruppo che include tutti di default), questo può aprire problemi di sicurezza altrove. E prima o poi, qualcosa rovinerà il tuo schema di autorizzazioni accuratamente predisposto, mettendo fuori uso il repository fino a quando non avrai rootaccesso e risolverlo (ad esempio, eseguendo nuovamente i comandi sopra).

La soluzione New Wave

Una soluzione superiore, sebbene meno ben compresa e che richiede un po 'più di supporto OS / tool, è quella di utilizzare gli attributi estesi POSIX. Sono venuto in quest'area solo di recente, quindi la mia conoscenza qui non è così calda come potrebbe essere. Ma fondamentalmente, un ACL esteso è la possibilità di impostare autorizzazioni su più dei 3 slot predefiniti (utente / gruppo / altro).

Quindi, ancora una volta, crea il tuo gruppo, quindi esegui:

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

Questo imposta l'ACL esteso per il gruppo in modo che i membri del gruppo possano leggere / scrivere / accedere a qualsiasi file sia già presente (la prima riga); quindi, dire anche a tutte le directory esistenti che ai nuovi file dovrebbe essere applicato lo stesso ACL (la seconda riga).

Spero che ti porti sulla buona strada.


62
git init ha un parametro chiamato --shared che imposta la variabile core.sharedRepository per il lavoro di gruppo. È inoltre possibile impostare la variabile su un repository esistente. Ciò elimina la necessità di impostare manualmente umask come git lo imposterà su un valore sano prima di manipolare i file.
ptman,

6
+1 per gli attributi estesi POSIX - novità per me!
RobM,

5
Quando l'ho fatto chmod -R g+swX, ha reso Git molto infelice e ha deciso che non era più un repository git ("repository non sembra essere un repository git"). Ho dovuto modificare tutti i file . Per impostare semplicemente il bit setgid nelle directory , provare find /path/to/repo -type d -print0 | xargs -0 chmod g+s. Fai ancora il chgrp -R thegroup /path/to/repo.
rescdsk,

10
chmod -R g+swX gitrepoapplicherà il bit setguid ai file, il che rappresenta un rischio per la sicurezza. Invece, puoi usarlo find . -type d -exec chmod g+s {} +per applicarlo solo alle directory.
Ian Dunn,

1
ACL (setfacl) non ha impostazioni per setgid per imporre nuovi file e sottodirectory creati all'interno di una directory per ereditare il suo ID gruppo. Pertanto, è necessario impostare setgid separatamente tramite chmod. L'opzione --shared di Git ( git-scm.com/docs/git-init ), tuttavia, ti consente di impostaregid e sovrascrivere la umask dell'utente.
Chase T.

121

se hai creato il repository (o clonato un nuovo repository nudo da uno esistente) con

$ git init --shared=group 

o

$ git init --shared=0NNN

Si suppone che Git gestisca le autorizzazioni al di là di ciò che fornisce umask predefinito. Finalmente questo è vero sulla mia versione di Git (1.6.3). Naturalmente questo presuppone che i tuoi utenti appartengano allo stesso gruppo.

Se avessi bisogno della gestione degli utenti in più gruppi con vari gradi di lettura / scrittura, però, andrei con la gitosi. Ho anche sentito parlare di gitolite ( http://github.com/sitaramc/gitolite ), un fork di gitosi che dovrebbe fornire autorizzazioni a livello di filiale, ma non posso dire che l'ho usato tutti personalmente però.


9
Questa è sicuramente la risposta corretta.
ELLIOTTCABLE

4
Ho avuto questo problema e questa è di gran lunga la risposta migliore. L'unico problema è che l' --sharedargomento accetta un ottale, non esadecimale. Ho confermato questo nella fonte di Git 1.7.8 e il secondo esempio dovrebbe essere git init --shared=0NNN.
qpingu,

3
Che NNNcos'è la maschera di immissione o un numero di gruppo o qualcos'altro?
Craig McQueen,

20
A proposito, "gruppo" sopra è una parola chiave, non un segnaposto per il nome del tuo gruppo. Si assegna il gruppo usando il comando chgrp. Per un nuovo repository è git init --bare --shared=group myprojdove myproj è il nome del repository, seguito da chgrp -R mygroup myprojdove mygroup è il nome del gruppo.
labradort,

2
Fai notare che se i tuoi utenti si impegnano quando il loro gruppo predefinito è diverso da quello che dovrebbe essere, può rovinare tutto. Per risolvere questo problema, ogni utente dovrà raggruppare tutti i file che possiede nel repository nel gruppo giusto. Ciò si ripeterà a meno che tu non capisca come fare in modo che tutti creino / cambino i nuovi file nel / al gruppo giusto prima di eseguire il commit e il push.
ragerdl,

55

Questo non è stato detto, quindi voglio aggiungerlo rapidamente.

Per assicurarsi che i problemi con i permessi non si sfaldino, assicurati di impostare quanto segue sul file di configurazione del tuo repository condiviso git:

[core]
    sharedRepository = true

Ciò garantirà il rispetto delle impostazioni "umask" del sistema.


6
Secondo git-config (1) ( kernel.org/pub/software/scm/git/docs/git-config.html ) core.sharedRepository, è necessario impostarlo su "umask" o "false" per avere rispetto git umask dell'utente.
David Schmitt,

14
Questa e la risposta di user35117 è corretta. Notare che "true" è uguale a "group" e questo può essere impostato con il comando git config core.sharedRepository true.
ColinM,

Cambia ancora la proprietà di un file quando viene trasferito in remoto?
Duc Tran,

2
Se si desidera impostare questo durante la clonazione piuttosto che dopo il fatto, l'equivalente di git init --sharedè git clone --config core.sharedRepository=true. Strano di git da usare --sharedper significati così diversi in comandi simili.
stevek_mcc,

21

Il Manuale dell'utente di Git descrive come condividere un repository in diversi modi.

I modi più complicati, sebbene ricchi di funzionalità, per condividere i repository sono:

Usiamo GitHub per un team di 6 sviluppatori.


1
Mi piace la gitosi. È un modo abbastanza efficace per controllare l'accesso basato su chiavi pubbliche.
Mike Mazur,

In che modo una di queste soluzioni risolve il problema di "Vorrei che più persone attirassero quel repository"?
Womble

Dai un'occhiata alla gitosi. quello risolve il tuo problema.
pilif

3
Quando condividi il repository, le persone saranno in grado di estrarlo. Probabilmente dovranno clonarlo o aggiungere un ramo remoto. La documentazione che ho collegato ti guiderà molto chiaramente nella risoluzione del problema; Ho usato tutti i metodi descritti per aiutare gli sviluppatori a collaborare al codice sorgente con Git. Per quanto ne so, ServerFault non è per uso manuale.
jtimberman,

3
Sono d'accordo con l'uso di Gitosis. Risolve il problema delle autorizzazioni utilizzando un singolo account autenticato da più chiavi SSH. Inoltre è gestito interamente da solo tramite commit git.
Jeremy Bouse,

9

Guarda anche gitolite per ospitare il tuo repository git. Apparentemente la gitosi non viene più sviluppata.


4

Un modo per correggere le autorizzazioni nel repository condiviso, in modo che gli utenti non abbiano problemi di autorizzazione quando spingono, è quello di creare uno script hook post-aggiornamento che farà proprio questo. Questo dovrebbe funzionare in qualsiasi versione di git.

Supponiamo di avere un repository condiviso in /myrepo.git. Tutti i file in quel repository appartengono a mysharedgroup . Tutti gli utenti che spingono verso quel repository dovrebbero appartenere anche a mysharedgroup . Ora crea il seguente file (cambiando mysharedgroup alle tue preferenze):

/myrepo.git/hooks/post-update

#!/bin/sh
chmod -R g+w . 2>/dev/null
chgrp -R mysharedgroup . 2>/dev/null

la risposta giusta per quando gli utenti hanno gruppi predefiniti diversi
Pat

L'impostazione del bit setgid su una directory farà sì che i file creati dagli utenti ereditino la stessa proprietà del gruppo della directory (se gli utenti appartengono a quel gruppo). Anche se non è il gruppo predefinito degli utenti. Quindi questo gancio non è necessario. Questa è la risposta di @ womble (e il mio commento).
rescdsk,

Sulla mia macchina centos7, dopo aver provato tutte le soluzioni elencate in questa pagina, una variante della soluzione di @ bkmks sopra era l'unica opzione che funzionava effettivamente (impostando gli hook post-merge e post-checkout invece di post-update come sopra).
Mike Godin,

Penso che sia un cattivo consiglio promuovere una soluzione che installi messaggi di errore o avvertenze su STDER /dev/null. Si prega di far vedere all'utente prima questi messaggi e poi decidere autonomamente.
Daniel Böhmer,

3

Per aggregare i pezzi di buoni consigli dalle varie altre risposte e commenti sull'impostazione di un nuovo repository:

Se si sta impostando un nuovo repo myrepoin /srv/gitper il gruppo mygroup, questo è ciò che si vuole:

mkdir /srv/git/myrepo.git
chgrp mygroup /srv/git/myrepo.git
git init --bare --shared /srv/git/myrepo.git
  1. la prima riga crea la directory repo
  2. la seconda riga imposta il suo gruppo su mygroup
  3. la terza riga inizializza un repository nudo con la seguente configurazione:
    1. core.bare = true: rendilo un repository nudo
    2. core.sharedrepository = 1(uguale a core.sharedrepository = group): la directory di repository e tutte le directory create successivamente saranno gestite da git per consentire le autorizzazioni di mygrouplettura, scrittura ed esecuzione (anche con il bit sgid impostato - in modo da lavorare con utenti per i quali mygroupnon è loro gruppo primario)
    3. receive.denyNonFastforwards = 1: nega push non in avanti veloce al repository

Se vuoi mettere a punto le autorizzazioni dell'utente, del gruppo o di altri utenti, usa --shared=0NNN, dove NNNsono l'utente standard, il gruppo e altri bit per i file (i bit di esecuzione e sgid nelle directory saranno gestiti in modo appropriato da git). Ad esempio, ciò consente l'accesso in lettura e scrittura all'utente e l'accesso in sola lettura al gruppo (e nessun accesso ad altri):

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

Ciò consente l'accesso in lettura e scrittura all'utente e al gruppo (e nessun accesso ad altri):

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

Ciò consente l'accesso in lettura e scrittura all'utente e al gruppo e l'accesso in sola lettura ad altri:

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

Si noti che se non si consente l'accesso in scrittura al gruppo, assicurarsi di utilizzare prima chownper impostare il proprietario del repository, quindi eseguire il git initcomando come tale utente (per assicurarsi che il repository sia inizializzato con il proprietario corretto per tutti i file e le sottodirectory iniziali).


Più corretto delle risposte di voto più alte.
XO01


1

Fare esattamente questo ha funzionato per me, per un repository esistente. Questo richiede consigli da diverse risposte e commenti prima:

Dalla directory principale del repository, sul server:

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

0

La risposta di @stevek_mcc è quella che stavo cercando quando ho cercato su Google questa domanda

git clone --config core.sharedRepository=true
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.