Jak udostępnić repozytorium Git wielu użytkownikom na komputerze?

216

Mam repozytorium Git na serwerze pomostowym, do którego musi być zdolnych wielu programistów. git-initwydaje się mieć flagę bardzo zbliżoną do tego, czego szukam: --sharedoprócz tego, że chciałbym, aby wiele osób również przyciągnęło do tego repozytorium. git-clone„S --sharedflag robi coś zupełnie innego.

Jaki jest najłatwiejszy sposób zmiany uprawnień istniejącego repozytorium?

Andriej Fiodorow
źródło
Używam „Github dla Windows” i przełączam się między dwoma kontami Github: stackoverflow.com/questions/18565876/...
Alisa

Odpowiedzi:

186

Uprawnienia są szkodnikiem.

Zasadniczo musisz upewnić się, że wszyscy ci programiści mogą pisać do wszystkiego w repozytorium git.

Przejdź do rozwiązania New-Wave, aby uzyskać najlepszą metodę przyznawania grupie programistów możliwości pisania.

Standardowe rozwiązanie

Jeśli umieścisz wszystkich programistów w specjalnie utworzonej grupie, możesz w zasadzie po prostu:

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

Następnie zmień umaskdla użytkowników na 002, aby nowe pliki były tworzone z uprawnieniami do zapisu w grupie.

Problemami z tym są legion; jeśli jesteś na distro, które przyjmuje umaskz 022(jak mają wspólną usersgrupę, która obejmuje każdy domyślnie), to może otworzyć się problemy związane z bezpieczeństwem w innym miejscu. A wcześniej czy później coś spieprzy twój starannie spreparowany schemat uprawnień, wyłączając repozytorium z działania, dopóki nie uzyskasz rootdostępu i nie naprawisz go (tj. Ponownie uruchomisz powyższe polecenia).

Rozwiązanie nowej fali

Lepszym rozwiązaniem - choć mniej zrozumiałym i wymagającym nieco większej obsługi systemu / narzędzi - jest użycie rozszerzonych atrybutów POSIX. Przybyłem do tego obszaru dopiero niedawno, więc moja wiedza tutaj nie jest tak gorąca, jak mogłaby być. Ale w zasadzie rozszerzona lista ACL to możliwość ustawiania uprawnień dla więcej niż tylko 3 domyślnych miejsc (użytkownik / grupa / inny).

Więc jeszcze raz utwórz grupę, a następnie uruchom:

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

To konfiguruje rozszerzoną listę ACL dla grupy, aby członkowie grupy mogli czytać / zapisywać / uzyskiwać dostęp do wszystkich plików, które już tam są (pierwsza linia); następnie powiedz wszystkim istniejącym katalogom, że nowe pliki powinny mieć tę samą listę ACL (drugi wiersz).

Mam nadzieję, że to cię poprowadzi.

womble
źródło
62
git init ma parametr o nazwie --shared, który ustawia zmienną core.sharedRepository do pracy w grupie. Możesz także ustawić zmienną w istniejącym repozytorium. To eliminuje potrzebę ręcznego ustawiania umask, ponieważ git ustawi go na rozsądną wartość przed manipulowaniem plikami.
ptman
6
+1 dla rozszerzonych atrybutów POSIX - wiadomość dla mnie!
RobM,
5
Kiedy to zrobiłem chmod -R g+swX, sprawiło, że Git był bardzo niezadowolony i zdecydował, że nie jest już repozytorium git („repo nie wydaje się być repozytorium git”). Musiałem przeskoczyć wszystkie pliki . Aby ustawić bit setgid w katalogach , spróbuj find /path/to/repo -type d -print0 | xargs -0 chmod g+s. Nadal rób chgrp -R thegroup /path/to/repo.
rescdsk,
10
chmod -R g+swX gitrepozastosuje bit setguid do plików, co stanowi zagrożenie bezpieczeństwa. Zamiast tego możesz użyć, find . -type d -exec chmod g+s {} +aby zastosować go tylko do katalogów.
Ian Dunn,
1
ACL (setfacl) nie ma ustawienia dla setgid do wymuszania nowych plików i podkatalogów utworzonych w katalogu w celu dziedziczenia jego identyfikatora grupy. Dlatego musisz ustawić setgid osobno poprzez chmod. Opcja Gsh --shared ( git-scm.com/docs/git-init ) pozwala jednak ustawić gid i przesłonić umask użytkownika.
Chase T.
121

jeśli utworzyłeś repozytorium (lub sklonowałeś nowe repozytorium od istniejącego) za pomocą

$ git init --shared=group 

lub

$ git init --shared=0NNN

Git powinien obsługiwać uprawnienia wykraczające poza to, co zapewnia domyślna umask. W końcu dotyczy to mojej wersji Git (1.6.3). Oczywiście zakłada to, że użytkownicy należą do tej samej grupy.

Gdybym jednak potrzebował zarządzania użytkownikami w wielu grupach o różnym stopniu odczytu / zapisu, wybrałbym gitosis. Słyszałem również o gitolicie ( http://github.com/sitaramc/gitolite ), widelcu gitosis, który ma zapewniać uprawnienia na poziomie oddziału, ale nie mogę powiedzieć, że każdy z nich osobiście go używał.

Dom na plaży
źródło
9
To zdecydowanie poprawna odpowiedź.
ELLIOTTCABLE,
4
Miałem ten problem i jest to zdecydowanie najlepsza odpowiedź. Jedynym problemem jest to, że --sharedargument przyjmuje liczbę ósemkową, a nie szesnastkową. Potwierdziłem to w źródle Gita 1.7.8, a drugim przykładem powinien być git init --shared=0NNN.
qpingu
3
Co to jest - NNNmaska ​​uprawnień, numer grupy lub coś innego?
Craig McQueen
20
BTW, „grupa” powyżej jest słowem kluczowym, a nie zastępczym dla nazwy grupy. Grupę przypisuje się za pomocą polecenia chgrp. W przypadku nowego repo to git init --bare --shared=group myprojmyproj to nazwa repo, a następnie chgrp -R mygroup myprojmygroup to nazwa grupy.
labradort
2
Heads up, że jeśli Twoi użytkownicy dokonują zatwierdzeń, gdy ich domyślna grupa jest inna niż powinna, może to popsuć. Aby rozwiązać ten problem, każdy użytkownik musi przeprogramować każdy plik, który posiada w repozytorium, do odpowiedniej grupy. To się powtórzy, chyba że wymyślisz, jak zmusić wszystkich do tworzenia / przełączania nowych plików w / do odpowiedniej grupy przed zatwierdzeniem i wypchnięciem.
ragerdl
55

Nie zostało to powiedziane, więc chcę to szybko dodać.

Aby mieć pewność, że problemy z uprawnieniami nie przycinają ich brzydkiej głowy, upewnij się, że ustawiłeś następujące ustawienia w pliku konfiguracyjnym repozytorium git:

[core]
    sharedRepository = true

Zapewni to przestrzeganie ustawień „umask” twojego systemu.

Niels Joubert
źródło
6
Zgodnie z git-config (1) ( kernel.org/pub/software/scm/git/docs/git-config.html ) core.sharedRepository, musisz ustawić to na „umask” lub „false”, aby mieć szacunek git umask użytkownika.
David Schmitt,
14
Ta odpowiedź użytkownika 35117 jest poprawna. Zauważ, że „prawda” to to samo, co „grupa”, i można to ustawić za pomocą polecenia git config core.sharedRepository true.
ColinM,
Czy nadal zmienia własność pliku, gdy jest on przekazywany do zdalnego?
Duc Tran
2
Jeśli chcesz to ustawić podczas klonowania, a nie po fakcie, odpowiednikiem git init --sharedjest git clone --config core.sharedRepository=true. Dziwne, że git używa --sharedtak różnych znaczeń w podobnych poleceniach.
stevek_mcc
21

Instrukcja obsługi Git opisuje sposób udostępniać repozytorium na kilka sposobów.

Bardziej skomplikowane, choć pełne funkcji sposoby udostępniania repozytoriów to:

Używamy GitHub dla zespołu 6 programistów.

jtimberman
źródło
1
Lubię Gitosis. Jest to dość skuteczny sposób kontrolowania dostępu w oparciu o klucze publiczne.
Mike Mazur,
W jaki sposób którekolwiek z tych rozwiązań rozwiązuje problem „Chciałbym, aby wiele osób przyciągało do tego repozytorium”?
womble
spójrz na gitosis. ten rozwiązuje twój problem.
pilif
3
Gdy udostępnisz repozytorium, ludzie będą mogli z niego korzystać. Prawdopodobnie będą musieli go sklonować lub dodać zdalną gałąź. Dokumentacja, którą podłączyłem, bardzo wyraźnie przeprowadzi cię przez proces rozwiązywania problemu; Użyłem wszystkich opisanych metod, aby pomóc programistom we współpracy z kodem źródłowym w Git. Według mojej wiedzy ServerFault nie służy do trzymania w ręku.
jtimberman
3
Muszę się zgodzić na używanie Gitosis. Rozwiązuje problem uprawnień, korzystając z jednego konta uwierzytelnionego za pomocą wielu kluczy SSH. Jest także zarządzany całkowicie sam przez git commits.
Jeremy Bouse
9

Spójrz także na gitolite, na którym znajduje się twoje repozytorium git. Gitoza najwyraźniej nie jest już rozwijana.

mt3
źródło
4

Jednym ze sposobów naprawy uprawnień we współdzielonym repozytorium, aby użytkownicy nie mieli problemów z uprawnieniami podczas wypychania, jest utworzenie skryptu przechwytującego po aktualizacji, który to zrobi. Powinno to działać w dowolnej wersji git.

Załóżmy, że masz wspólne repozytorium w /myrepo.git. Wszystkie pliki w tym repozytorium należą do grupy mysharedgroup . Wszyscy użytkownicy pchający do tego repozytorium powinni również należeć do mysharedgroup . Teraz utwórz następujący plik (zmieniając mysharedgroup na swoje preferencje):

/myrepo.git/hooks/post-update

#!/bin/sh
chmod -R g+w . 2>/dev/null
chgrp -R mysharedgroup . 2>/dev/null
bkmks
źródło
właściwa odpowiedź, gdy użytkownicy mają różne grupy domyślne
Pat
Ustawienie bitu setgid w katalogu spowoduje, że tworzone przez użytkowników pliki odziedziczą tę samą własność grupy co katalog (jeśli użytkownicy należą do tej grupy). Nawet jeśli nie jest to domyślna grupa użytkowników. Wtedy ten hak nie jest potrzebny. Oto, co robi odpowiedź @ womble (i mój komentarz na ten temat).
rescdsk,
Na moim komputerze centos7, po wypróbowaniu każdego rozwiązania wymienionego na tej stronie, wariant rozwiązania @ bkmks powyżej był jedyną opcją, która faktycznie działała (ustawienie haków po scaleniu i po pobraniu zamiast po aktualizacji, jak powyżej).
Mike Godin
Myślę, że zła rada to promowanie rozwiązania, które przekazuje komunikaty o błędach lub ostrzeżenia na STDER do /dev/null. Pozwól użytkownikowi najpierw zobaczyć te wiadomości, a następnie zdecydować samodzielnie.
Daniel Böhmer,
3

Aby zebrać fragmenty dobrych rad z różnych innych odpowiedzi i komentarzy na temat tworzenia nowego repozytorium:

Jeśli utworzenie nowy repo myrepow /srv/gitdla grupy mygroup, to jest to, co chcesz:

mkdir /srv/git/myrepo.git
chgrp mygroup /srv/git/myrepo.git
git init --bare --shared /srv/git/myrepo.git
  1. pierwsza linia tworzy katalog repo
  2. druga linia ustawia swoją grupę na mygroup
  3. trzeci wiersz inicjuje nagie repozytorium w następującej konfiguracji:
    1. core.bare = true: spraw, aby było to proste repo
    2. core.sharedrepository = 1(to samo co core.sharedrepository = group): katalog repo i wszystkie później utworzone w nim katalogi będą zarządzane przez git, aby zezwolić na mygroupodczyt, zapis i wykonywanie uprawnień (z ustawionym bitem sgid - tak, aby pracować z użytkownikami, dla których mygroupnie jest ich grupa podstawowa)
    3. receive.denyNonFastforwards = 1: nie zezwalaj na przekazywanie repozytoriów bez przewijania do przodu

Jeśli chcesz dostroić uprawnienia użytkownika, grupy lub innych użytkowników, użyj --shared=0NNN, gdzie NNNsą standardowe bity użytkownika, grupy i inne bity dla plików (bity wykonania i sgid w katalogach będą odpowiednio zarządzane przez git). Na przykład umożliwia to dostęp do odczytu i zapisu użytkownikowi oraz dostęp tylko do odczytu do grupy (i brak dostępu do innych):

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

Umożliwia to dostęp do odczytu i zapisu użytkownikowi i grupie (i nie ma dostępu do innych):

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

Umożliwia to dostęp do odczytu i zapisu użytkownikowi i grupie oraz dostęp tylko do odczytu do innych:

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

Zauważ, że jeśli nie zamierzasz zezwalać na dostęp do zapisu w grupie, upewnij się, że najpierw użyłeś, chownaby ustawić właściciela repo, a następnie uruchom git initkomendę jako ten użytkownik (aby upewnić się, że repo zostało zainicjowane z poprawnym właścicielem dla wszystkie początkowe pliki i podkatalogi).

Justin Ludwig
źródło
Bardziej poprawne niż wyższe odpowiedzi głosowania.
XO01,
1

Wykonanie dokładnie tego działało dla mnie, dla istniejącego repozytorium. To wymaga porady z kilku odpowiedzi i komentarzy wcześniej:

Z katalogu nadrzędnego repozytorium na serwerze:

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
źródło
0

Odpowiedź @stevek_mcc jest tą, której szukałem, kiedy przejrzałem to pytanie

git clone --config core.sharedRepository=true
ragerdl
źródło