Wie teile ich ein Git-Repository mit mehreren Benutzern auf einem Computer?

216

Ich habe ein Git-Repository auf einem Staging-Server, auf den mehrere Entwickler zugreifen können müssen. git-initscheint eine Flagge zu haben, die sehr nahe an dem ist, wonach ich suche:, --sharedaußer dass ich möchte, dass auch mehrere Personen in dieses Repository ziehen. Die git-clone‚s --sharedFlagge tut etwas ganz anderes.

Was ist der einfachste Weg, um die Berechtigungen eines vorhandenen Repositorys zu ändern?

Andrey Fedorov
quelle
Ich verwende "Github für Windows" und wechsle
Alisa

Antworten:

186

Berechtigungen sind eine Plage.

Grundsätzlich müssen Sie sicherstellen, dass alle diese Entwickler auf alles im Git-Repo schreiben können.

Fahren Sie mit The New-Wave Solution fort, um zu erfahren, wie Sie einer Gruppe von Entwicklern überlegene Schreibrechte erteilen können.

Die Standardlösung

Wenn Sie alle Entwickler in einer speziell erstellten Gruppe zusammenfassen, können Sie im Prinzip einfach Folgendes tun:

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

Ändern Sie dann die umaskfür die Benutzer in 002, damit neue Dateien mit gruppenbeschreibbaren Berechtigungen erstellt werden.

Die Probleme damit sind Legion; Wenn Sie sich in einer Distribution befinden, die eine umaskvon 022(z. B. eine gemeinsame usersGruppe mit standardmäßig allen Benutzern) annimmt , kann dies zu Sicherheitsproblemen an anderer Stelle führen. Und früher oder später wird etwas Ihr sorgfältig ausgearbeitetes Berechtigungsschema durcheinander bringen und das Repo außer Betrieb setzen, bis Sie rootZugriff erhalten und es reparieren (dh die obigen Befehle erneut ausführen).

Die New-Wave-Lösung

Eine überlegene Lösung, die zwar weniger bekannt ist und etwas mehr Unterstützung für Betriebssysteme und Tools erfordert, ist die Verwendung erweiterter POSIX-Attribute. Ich bin erst vor kurzem in dieses Gebiet gekommen, daher ist mein Wissen hier nicht so heiß, wie es sein könnte. Grundsätzlich ist eine erweiterte ACL jedoch die Möglichkeit, Berechtigungen für mehr als nur die drei Standardsteckplätze (Benutzer / Gruppe / Andere) festzulegen.

Erstellen Sie also noch einmal Ihre Gruppe und führen Sie dann Folgendes aus:

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

Dies richtet die erweiterte ACL für die Gruppe ein, so dass die Gruppenmitglieder lesen / schreiben / auf alle Dateien zugreifen können, die bereits vorhanden sind (die erste Zeile). Teilen Sie anschließend allen vorhandenen Verzeichnissen mit, dass auf neue Dateien dieselbe ACL angewendet werden soll (zweite Zeile).

Hoffe das bringt dich auf den Weg.

womble
quelle
62
git init hat einen Parameter namens --shared, der die Variable core.sharedRepository für die Gruppenarbeit einrichtet. Sie können die Variable auch in einem vorhandenen Repository festlegen. Dadurch muss die umask nicht mehr manuell eingestellt werden, da git sie vor dem Bearbeiten von Dateien auf einen vernünftigen Wert setzt.
Ptman
6
+1 für erweiterte POSIX-Attribute - Neuigkeiten für mich!
RobM
5
Als ich das tat chmod -R g+swX, machte es Git sehr unglücklich und entschied, dass es kein Git-Repository mehr war ("repo scheint kein Git-Repository zu sein"). Ich musste alle Dateien ändern . Versuchen Sie, nur das Setgid-Bit in den Verzeichnissen zu setzenfind /path/to/repo -type d -print0 | xargs -0 chmod g+s . Mach immer noch das chgrp -R thegroup /path/to/repo.
Rescdsk
10
chmod -R g+swX gitrepoWendet das Setguid-Bit auf Dateien an, was ein Sicherheitsrisiko darstellt. Stattdessen können Sie find . -type d -exec chmod g+s {} +es nur auf Verzeichnisse anwenden.
Ian Dunn
1
ACL (setfacl) hat keine Einstellung für setgid, um neue Dateien und Unterverzeichnisse zu erzwingen, die in einem Verzeichnis erstellt wurden, um dessen Gruppen-ID zu erben. Daher müssen Sie setgid separat über chmod einstellen. Mit der Option --shared von Git ( git-scm.com/docs/git-init ) können Sie jedoch die umask des Benutzers festlegen und überschreiben.
Chase T.
121

wenn Sie das Repository erstellt haben (oder ein neues Bare-Repository von einem vorhandenen geklont haben) mit

$ git init --shared=group 

oder

$ git init --shared=0NNN

Git soll Berechtigungen verarbeiten, die über das hinausgehen, was Ihre Standard-Umask bietet. Endlich trifft dies auf meine Version von Git (1.6.3) zu. Dies setzt natürlich voraus, dass sich Ihre Benutzer in derselben Gruppe befinden.

Wenn ich jedoch die Verwaltung von Benutzern in mehreren Gruppen mit unterschiedlichem Lese- / Schreibgrad benötigte, würde ich mich für Gitosis entscheiden. Ich habe auch die Erwähnung von Gitolite ( http://github.com/sitaramc/gitolite ) gehört, einer Gitosisgabel, von der angenommen wird, dass sie Berechtigungen auf Zweigebene bietet. Ich kann jedoch nicht sagen, dass ich sie von jedem persönlich verwendet habe.

Strandhaus
quelle
9
Dies ist definitiv die richtige Antwort.
ELLIOTTCABLE
4
Ich hatte dieses Problem und dies ist bei weitem die beste Antwort. Das einzige Problem ist, dass das --sharedArgument ein Oktal und kein Hexadezimal enthält. Ich habe dies in der Quelle von Git 1.7.8 bestätigt und das zweite Beispiel sollte es sein git init --shared=0NNN.
Qpingu
3
Was ist eine NNNBerechtigungsmaske oder eine Gruppennummer oder etwas anderes?
Craig McQueen
20
Übrigens ist "Gruppe" oben ein Schlüsselwort und kein Platzhalter für Ihren Gruppennamen. Sie weisen die Gruppe mit dem Befehl chgrp zu. Bei einem neuen Repo steht git init --bare --shared=group myprojmyproj für Ihren Repo-Namen, gefolgt von chgrp -R mygroup myprojmygroup für Ihren Gruppennamen.
Labradort
2
Wenn Ihre Benutzer Commits machen, wenn ihre Standardgruppe anders ist als sie sein sollte, kann dies zu Misserfolgen führen. Um dieses Problem zu beheben, muss jeder Benutzer jede Datei, die er im Repo besitzt, in die richtige Gruppe verschieben. Dies wird wiederholt, es sei denn, Sie finden heraus, wie Sie alle dazu bringen, neue Dateien unter / in die richtige Gruppe zu erstellen / zu verschieben, bevor Sie einen Commit durchführen und einen Push ausführen.
Ragerdl
55

Dies wurde nicht gesagt, deshalb möchte ich es schnell hinzufügen.

Stellen Sie in der Konfigurationsdatei Ihres git shared repositorys Folgendes sicher, um sicherzustellen, dass Berechtigungsprobleme nicht zu einem unerwünschten Ergebnis führen:

[core]
    sharedRepository = true

Dadurch wird sichergestellt, dass die "umask" -Einstellungen Ihres Systems eingehalten werden.

Niels Joubert
quelle
6
Laut git-config (1) ( kernel.org/pub/software/scm/git/docs/git-config.html ) core.sharedRepository müssen Sie dies auf "umask" oder "false" setzen, um git-Respekt zu haben die umask des Benutzers.
David Schmitt
14
Diese und user35117s Antwort ist korrekt. Beachten Sie, dass "true" dasselbe ist wie "group" und dies kann mit dem Befehl eingestellt werden git config core.sharedRepository true.
ColinM
Ändert es immer noch den Besitz einer Datei, wenn sie auf Remote übertragen wird?
Duc Tran
2
Wenn Sie dies eher beim Klonen als nachträglich einrichten möchten, git init --sharedlautet das Äquivalent von git clone --config core.sharedRepository=true. Seltsamerweise --sharedfür so unterschiedliche Bedeutungen in so ähnlichen Befehlen zu verwenden.
stevek_mcc
21

Das Git-Benutzerhandbuch beschreibt auf verschiedene Arten, wie Sie ein Repository freigeben.

Kompliziertere, aber funktionsreiche Möglichkeiten zum Freigeben von Repositorys sind:

Wir verwenden GitHub für ein Team von 6 Entwicklern.

jtimberman
quelle
1
Ich mag Gitosis. Dies ist eine sehr effektive Methode, um den Zugriff auf Basis öffentlicher Schlüssel zu steuern.
Mike Mazur
Wie löst eine dieser Lösungen das Problem "Ich möchte, dass mehrere Personen in dieses Repository ziehen"?
womble
schau dir gitosis an. Das löst dein Problem.
Pilif
3
Wenn Sie das Repository freigeben, können andere Benutzer darauf zugreifen. Sie müssen es wahrscheinlich klonen oder einen Remote-Zweig hinzufügen. Die Dokumentation, die ich verlinkt habe, wird Sie sehr deutlich durch die Lösung Ihres Problems führen. Ich habe alle beschriebenen Methoden verwendet, um Entwicklern bei der Zusammenarbeit von Quellcode mit Git zu helfen. Meines Wissens ist ServerFault nicht für das Handhaben gedacht.
jtimberman
3
Ich muss mit Gitosis einverstanden sein. Das Problem mit den Berechtigungen wird umgangen, indem ein einziges Konto verwendet wird, das von mehreren SSH-Schlüsseln authentifiziert wird. Es wird auch vollständig selbst über Git-Commits verwaltet.
Jeremy Bouse
9

Schauen Sie sich auch gitolite an, um Ihr Git-Repository zu hosten . Gitosis wird anscheinend nicht mehr entwickelt.

mt3
quelle
4

Eine Möglichkeit, Berechtigungen im freigegebenen Repository zu reparieren, damit Benutzer beim Pushen keine Berechtigungsprobleme haben, besteht darin, ein Hook-Skript nach dem Update zu erstellen, das genau das tut. Dies sollte in jeder Git-Version funktionieren.

Angenommen, Sie haben ein freigegebenes Repository in /myrepo.git. Alle Dateien in diesem Repository gehören zu mysharedgroup . Alle Benutzer, die in dieses Repository pushen , sollten ebenfalls zu mysharedgroup gehören . Erstellen Sie nun die folgende Datei (ändern Sie mysharedgroup nach Ihren Wünschen ):

/myrepo.git/hooks/post-update

#!/bin/sh
chmod -R g+w . 2>/dev/null
chgrp -R mysharedgroup . 2>/dev/null
bkmks
quelle
Die richtige Antwort, wenn Benutzer unterschiedliche Standardgruppen haben
Pat
Wenn Sie das Bit "setgid" für ein Verzeichnis festlegen, erben von Benutzern erstellte Dateien denselben Gruppeneigentum wie das Verzeichnis (wenn die Benutzer zu dieser Gruppe gehören). Auch wenn es nicht die Standardgruppe der Benutzer ist. Dann wird dieser Haken nicht benötigt. Dies ist die Antwort von @ womble (und mein Kommentar dazu).
Rescdsk
Nachdem ich auf meinem centos7-Computer alle auf dieser Seite aufgelisteten Lösungen ausprobiert hatte, war eine Variante der obigen @ bkmks-Lösung die einzige Option, die tatsächlich funktionierte (Festlegen der Hooks nach dem Zusammenführen und nach dem Auschecken anstatt nach dem Update wie oben).
Mike Godin
Ich halte es für einen schlechten Rat, für eine Lösung zu werben, die Fehlermeldungen oder Warnungen auf STDER weiterleitet /dev/null. Bitte lassen Sie den Benutzer diese Nachrichten zuerst sehen und entscheiden Sie dann selbst.
Daniel Böhmer
3

So fassen Sie die wichtigsten Ratschläge aus den verschiedenen anderen Antworten und Kommentaren zum Einrichten eines neuen Repos zusammen:

Wenn Sie eine brandneue Repo - Einrichtung sind myrepoin /srv/gitder Gruppe mygroup, ist es das , was Sie wollen:

mkdir /srv/git/myrepo.git
chgrp mygroup /srv/git/myrepo.git
git init --bare --shared /srv/git/myrepo.git
  1. In der ersten Zeile wird das Repository erstellt
  2. Die zweite Zeile setzt ihre Gruppe auf mygroup
  3. Die dritte Zeile initialisiert ein Bare-Repo mit der folgenden Konfiguration:
    1. core.bare = true: machen Sie es zu einem nackten Repo
    2. core.sharedrepository = 1(dasselbe wie core.sharedrepository = group): Das Repo-Verzeichnis und alle später darin erstellten Verzeichnisse werden von git verwaltet, um mygroupLese-, Schreib- und Ausführungsberechtigungen zu ermöglichen (wobei auch das Sgid-Bit gesetzt ist), um mit Benutzern zu arbeiten, für die mygroupes nicht das richtige ist Hauptgruppe)
    3. receive.denyNonFastforwards = 1: Nicht-Schnellvorlauf-Pushs an das Repo verweigern

Wenn Sie die Berechtigungen von Benutzern, Gruppen oder anderen Benutzern optimieren möchten, geben Sie an --shared=0NNN, wo NNNsich die Standardbenutzer-, Gruppen- und anderen Bits für Dateien befinden (die Ausführungs- und sgid-Bits für Verzeichnisse werden von git entsprechend verwaltet). Dies ermöglicht beispielsweise Lese- und Schreibzugriff auf den Benutzer und schreibgeschützten Zugriff auf die Gruppe (und keinen Zugriff auf andere):

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

Dies ermöglicht Lese- und Schreibzugriff auf den Benutzer und die Gruppe (und keinen Zugriff auf andere):

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

Dies ermöglicht den Lese- und Schreibzugriff auf den Benutzer und die Gruppe sowie den schreibgeschützten Zugriff auf andere:

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

Beachten Sie, dass Sie, wenn Sie keinen Schreibzugriff auf die Gruppe zulassen möchten, zuerst chownden Eigentümer des Repos festlegen und dann den git initBefehl als dieser Benutzer ausführen müssen (um sicherzustellen, dass das Repo mit dem richtigen Eigentümer für initialisiert wird alle Ausgangsdateien und Unterverzeichnisse).

Justin Ludwig
quelle
Richtiger als die Antworten mit höheren Stimmen.
XO01
1

Genau das hat bei mir funktioniert, bei einem vorhandenen Repository. Dies lässt sich aus mehreren Antworten und Kommentaren ableiten:

Aus Ihrem übergeordneten Repository-Verzeichnis auf dem 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
Luis de Arquer
quelle
0

@stevek_mcc Antwort ist die, nach der ich gesucht habe, als ich nach dieser Frage gegoogelt habe

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