Làm cách nào để chia sẻ kho Git với nhiều người dùng trên máy?


216

Tôi có kho lưu trữ Git trên máy chủ dàn mà nhiều nhà phát triển cần có khả năng kéo đến. git-initdường như có một lá cờ rất gần với những gì tôi đang tìm kiếm : --shared, ngoại trừ tôi cũng muốn nhiều người kéo đến kho lưu trữ đó. Các git-clone's --sharedcờ làm điều gì đó hoàn toàn khác nhau.

Cách dễ nhất để thay đổi quyền của kho lưu trữ hiện tại là gì?


Tôi đang sử dụng "Github cho Windows" và chuyển đổi giữa hai tài khoản Github: stackoverflow.com/questions/18565876/ hiệu
Alisa

Câu trả lời:


186

Quyền là một dịch hại.

Về cơ bản, bạn cần đảm bảo rằng tất cả các nhà phát triển đó có thể viết cho mọi thứ trong repo git.

Bỏ qua Giải pháp Làn sóng mới cho phương pháp ưu việt cấp cho một nhóm các nhà phát triển khả năng viết.

Giải pháp chuẩn

Nếu bạn đặt tất cả các nhà phát triển vào một nhóm được tạo đặc biệt, về nguyên tắc, bạn có thể làm:

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

Sau đó thay đổi umaskcho người dùng thành 002, để các tệp mới được tạo với quyền có thể ghi theo nhóm.

Các vấn đề với điều này là quân đoàn; nếu bạn đang ở trên một bản phân phối giả định một umasktrong số 022(chẳng hạn như có một usersnhóm chung bao gồm tất cả mọi người theo mặc định), điều này có thể mở ra các vấn đề bảo mật ở nơi khác. Và sớm hay muộn, một cái gì đó sẽ làm hỏng sơ đồ cấp phép được làm cẩn thận của bạn, khiến repo không hoạt động cho đến khi bạn có rootquyền truy cập và sửa nó (nghĩa là chạy lại các lệnh trên).

Giải pháp sóng mới

Một giải pháp ưu việt, mặc dù ít được hiểu rõ và đòi hỏi nhiều hơn một chút về hỗ trợ hệ điều hành / công cụ OS là sử dụng các thuộc tính mở rộng POSIX. Gần đây tôi chỉ đến khu vực này, vì vậy kiến ​​thức của tôi ở đây không nóng như nó có thể. Nhưng về cơ bản, ACL mở rộng là khả năng đặt quyền trên nhiều hơn 3 vị trí mặc định (người dùng / nhóm / người khác).

Vì vậy, một lần nữa, tạo nhóm của bạn, sau đó chạy:

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

Điều này thiết lập ACL mở rộng cho nhóm để các thành viên trong nhóm có thể đọc / ghi / truy cập bất kỳ tệp nào đã có (dòng đầu tiên); sau đó, cũng nói với tất cả các thư mục hiện có rằng các tệp mới sẽ được áp dụng cùng ACL này (dòng thứ hai).

Hy vọng rằng có được bạn trên con đường của bạn.


62
git init có một tham số gọi là - shared để thiết lập biến core. SharedRep repository cho công việc nhóm. Bạn cũng có thể đặt biến trên một kho lưu trữ hiện có. Điều đó loại bỏ sự cần thiết phải cài đặt thủ công vì git sẽ đặt nó thành giá trị lành mạnh trước khi thao tác với các tệp.
ptman

6
+1 cho các thuộc tính mở rộng POSIX - tin tức với tôi!
RobM

5
Khi tôi làm vậy chmod -R g+swX, nó làm cho Git rất không hài lòng và nó quyết định nó không còn là kho lưu trữ git nữa ("repo dường như không phải là kho lưu trữ git"). Tôi đã phải chmod gs tất cả các tập tin . Để chỉ thiết lập bit setgid trên các thư mục , hãy thử find /path/to/repo -type d -print0 | xargs -0 chmod g+s. Vẫn làm chgrp -R thegroup /path/to/repo.
rescdsk

10
chmod -R g+swX gitreposẽ áp dụng bit setguid cho các tệp, đây là một rủi ro bảo mật. Thay vào đó, bạn có thể sử dụng find . -type d -exec chmod g+s {} +để chỉ áp dụng nó cho các thư mục.
Ian Dunn

1
ACL (setfacl) không có cài đặt cho setgid để thực thi các tệp và thư mục con mới được tạo trong một thư mục để kế thừa ID nhóm của nó. Do đó, bạn phải đặt setgid riêng thông qua chmod. Tuy nhiên, tùy chọn chia sẻ của Git ( git-scm.com/docs/git-init ), tuy nhiên, cho phép bạn thiết lập và ghi đè lên ô của người dùng.
Đuổi theo T.

121

nếu bạn đã tạo kho lưu trữ (hoặc nhân bản một repo trần mới ra khỏi kho lưu trữ hiện có) với

$ git init --shared=group 

hoặc là

$ git init --shared=0NNN

Git có nhiệm vụ xử lý các quyền ở trên và vượt ra ngoài những gì ô mặc định của bạn cung cấp. Cuối cùng, điều này đúng với phiên bản Git của tôi (1.6.3). Tất nhiên điều này giả sử người dùng của bạn thuộc cùng một nhóm.

Tuy nhiên, nếu tôi cần quản lý người dùng trong nhiều nhóm với mức độ đọc / ghi khác nhau, tôi sẽ bị bệnh gitosis. Tôi cũng đã nghe đề cập đến gitolite ( http://github.com/sitaramc/gitolite ), một ngã ba gitosis được cung cấp để cung cấp quyền cấp chi nhánh, mặc dù vậy tôi không thể nói rằng tôi đã từng sử dụng nó một cách cá nhân.


9
Đây chắc chắn là câu trả lời chính xác.
ELLIOTTCABLE

4
Tôi đã có vấn đề này và đây là câu trả lời tốt nhất. Vấn đề duy nhất là --sharedđối số mất trong một bát phân, không phải là thập lục phân. Tôi đã xác nhận điều này trong nguồn Git 1.7.8 và ví dụ thứ hai nên có git init --shared=0NNN.
qpingu

3
Là gì NNNmặt nạ -permissions hoặc một số nhóm hay cái gì khác?
Craig McQueen

20
BTW, "nhóm" ở trên là một từ khóa, không phải là một giữ chỗ cho tên nhóm của bạn. Bạn chỉ định nhóm bằng lệnh chgrp. Đối với một repo mới, đó là git init --bare --shared=group myprojnơi myproj là tên repo của bạn, theo sau là chgrp -R mygroup myprojmygroup là tên nhóm của bạn.
labradort

2
Cảnh báo rằng nếu người dùng của bạn thực hiện các cam kết khi nhóm mặc định của họ khác với những gì nó cần, thì nó có thể làm hỏng mọi thứ. Để khắc phục sự cố này, bạn sẽ cần mỗi người dùng chọn từng tệp mà họ sở hữu trong repo cho đúng nhóm. Điều này sẽ tái diễn trừ khi bạn tìm ra cách làm cho mọi người tạo / chuyển các tệp mới theo / sang đúng nhóm trước khi cam kết và đẩy.
ragerdl

55

Điều này chưa được nói, vì vậy tôi muốn nhanh chóng thêm nó.

Để đảm bảo rằng các vấn đề về quyền không cắt đầu xấu xí của chúng, hãy đảm bảo đặt các mục sau trên tệp cấu hình của kho lưu trữ chia sẻ git của bạn:

[core]
    sharedRepository = true

Điều này sẽ đảm bảo rằng các cài đặt "umask" của hệ thống của bạn được tuân thủ.


6
Theo git-config (1) ( kernel.org/pub/software/scm/git/docs/git-config.html ) core. SharedRep repository, bạn cần đặt điều này thành "umask" hoặc "false" để có sự tôn trọng git ô của người dùng.
David Schmitt

14
Câu trả lời này và user35117 là chính xác. Lưu ý rằng "true" giống như "nhóm" và điều này có thể được đặt bằng lệnh git config core.sharedRepository true.
ColinM

Nó vẫn thay đổi quyền sở hữu của một tập tin khi nó được đẩy đến từ xa?
Đức Trần

2
Nếu bạn muốn thiết lập điều này khi nhân bản thay vì sau khi thực tế, tương đương git init --sharedgit clone --config core.sharedRepository=true. Strange của git để sử dụng --sharedcho các ý nghĩa khác nhau trong các lệnh tương tự như vậy.
stevek_mcc

21

Các Git Hướng dẫn sử dụng mô tả làm thế nào để chia sẻ một kho lưu trữ theo nhiều cách.

Các cách phức tạp hơn, mặc dù đầy đủ tính năng để chia sẻ kho lưu trữ là:

Chúng tôi sử dụng GitHub cho một nhóm gồm 6 nhà phát triển.


1
Tôi thích Gitosis. Đây là một cách khá hiệu quả để kiểm soát truy cập dựa trên các khóa công khai.
Mike Mazur

Làm thế nào để bất kỳ giải pháp nào trong số này giải quyết vấn đề "Tôi muốn nhiều người kéo đến kho lưu trữ đó"?
womble

có một cái nhìn về bệnh gitosis. cái đó giải quyết vấn đề của bạn
pilif

3
Khi bạn chia sẻ kho lưu trữ, mọi người sẽ có thể lấy từ đó. Họ có thể sẽ cần sao chép nó hoặc thêm một nhánh từ xa. Các tài liệu tôi liên kết sẽ giúp bạn giải quyết vấn đề của bạn một cách rõ ràng; Tôi đã sử dụng tất cả các phương pháp được mô tả để giúp các nhà phát triển cộng tác mã nguồn với Git. Theo hiểu biết của tôi, ServerFault không dành cho việc nắm giữ.
jtimberman

3
Tôi phải đồng ý với việc sử dụng Gitosis. Nó giải quyết vấn đề về quyền bằng cách sử dụng một tài khoản được xác thực bằng nhiều khóa SSH. Nó cũng được quản lý hoàn toàn thông qua cam kết git.
Jeremy Bouse

9

Cũng nhìn vào gitolite để lưu trữ kho git của bạn. Gitosis dường như không được phát triển nữa.


4

Một cách để sửa quyền trong kho lưu trữ được chia sẻ, vì vậy người dùng sẽ không gặp vấn đề về quyền khi đẩy, là tạo tập lệnh hook sau cập nhật sẽ làm việc đó. Điều này sẽ làm việc trong bất kỳ phiên bản git.

Giả sử bạn có một kho lưu trữ được chia sẻ trong /myrepo.git. Tất cả các tệp trong kho lưu trữ đó thuộc về nhóm chia sẻ của tôi . Tất cả người dùng đẩy vào kho lưu trữ đó cũng thuộc về nhóm chia sẻ của tôi . Bây giờ hãy tạo tệp sau (thay đổi nhóm chia sẻ của tôi thành tùy chọn của bạn):

/myrepo.git/hooks/post-update

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

câu trả lời đúng khi người dùng có các nhóm mặc định khác nhau
Pat

Đặt bit setgid trên một thư mục sẽ khiến các tệp mà người dùng tạo để kế thừa quyền sở hữu nhóm giống như thư mục (nếu người dùng thuộc nhóm đó). Ngay cả khi đó không phải là nhóm mặc định của người dùng. Sau đó, cái móc này là không cần thiết. Đây là những gì câu trả lời của @ womble (và nhận xét của tôi về nó) làm.
rescdsk

Trên máy centos7 của tôi, sau khi thử mọi giải pháp được liệt kê trên trang này, một biến thể của giải pháp @ bkmks ở trên là tùy chọn duy nhất thực sự hoạt động (cài đặt các móc nối sau hợp nhất và sau thanh toán thay vì cập nhật sau như trên).
Mike Godin

Tôi nghĩ rằng đó là lời khuyên tồi để quảng bá một giải pháp mà thông báo lỗi hoặc cảnh báo về ĐẶT HÀNG /dev/null. Vui lòng cho người dùng thấy những tin nhắn này trước và sau đó tự quyết định.
Daniel Böhmer

3

Để tổng hợp các bit và mẩu lời khuyên tốt từ các câu trả lời và nhận xét khác nhau về việc thiết lập một repo mới:

Nếu bạn đang thiết lập một repo mới toanh myrepotrong /srv/gitcho nhóm mygroup, đây là những gì bạn muốn:

mkdir /srv/git/myrepo.git
chgrp mygroup /srv/git/myrepo.git
git init --bare --shared /srv/git/myrepo.git
  1. dòng đầu tiên tạo ra repo dir
  2. dòng thứ hai đặt nhóm của nó thành mygroup
  3. dòng thứ ba khởi tạo một repo trần với cấu hình sau:
    1. core.bare = true: làm cho nó một repo trần
    2. core.sharedrepository = 1(giống như core.sharedrepository = group): thư mục repo và tất cả các thư mục được tạo trong đó sẽ được quản lý bởi git để cho phép mygroupđọc, ghi và thực thi các quyền (với bit sgid được đặt - để làm việc với người dùng mygroupkhông phải là của họ nhóm chính)
    3. receive.denyNonFastforwards = 1: từ chối đẩy không nhanh về phía repo

Nếu bạn muốn tinh chỉnh quyền của người dùng, nhóm hoặc quyền của người dùng khác, hãy sử dụng --shared=0NNN, nơi NNNngười dùng chuẩn, nhóm và các bit khác cho các tệp (các bit thực thi và sgid trên các thư mục sẽ được git quản lý một cách thích hợp). Ví dụ: điều này cho phép đọc và ghi quyền truy cập vào người dùng và quyền truy cập chỉ đọc vào nhóm (và không có quyền truy cập vào nhóm khác):

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

Điều này cho phép đọc và ghi quyền truy cập vào người dùng và nhóm (và không có quyền truy cập khác):

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

Điều này cho phép truy cập đọc và ghi vào người dùng và nhóm và truy cập chỉ đọc cho người khác:

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

Lưu ý rằng nếu bạn sẽ không cho phép truy cập ghi vào nhóm, trước tiên hãy đảm bảo sử dụng chownđể đặt chủ sở hữu của repo và sau đó chạy git initlệnh với tư cách là người dùng đó (để đảm bảo repo được khởi tạo với chủ sở hữu chính xác cho tất cả các tập tin ban đầu và thư mục con).


Chính xác hơn các phản hồi bỏ phiếu cao hơn.
XO01


1

Làm chính xác điều này làm việc cho tôi, cho một kho lưu trữ hiện có. Điều này cần lời khuyên từ một số câu trả lời và ý kiến ​​trước:

Từ thư mục mẹ kho lưu trữ của bạn, tại máy chủ:

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

@stevek_mcc câu trả lời là câu hỏi mà tôi đang tìm kiếm khi tôi tìm kiếm câu hỏi này

git clone --config core.sharedRepository=true
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.