Bagaimana cara saya berbagi repositori Git dengan banyak pengguna di mesin?

216

Saya memiliki repositori Git pada server pementasan yang beberapa pengembang harus dapat menariknya. git-inittampaknya memiliki bendera yang sangat dekat dengan apa yang saya cari --shared:, kecuali saya ingin beberapa orang menarik ke repositori itu, juga. The git-clone's --sharedbendera melakukan sesuatu yang sama sekali berbeda.

Apa cara termudah untuk mengubah izin repositori yang ada?

Andrey Fedorov
sumber
Saya menggunakan "Github untuk Windows" dan beralih di antara dua akun Github: stackoverflow.com/questions/18565876/…
Alisa

Jawaban:

186

Izin adalah hama.

Pada dasarnya, Anda perlu memastikan bahwa semua pengembang tersebut dapat menulis ke semua yang ada di git repo.

Lewati ke The New-Wave Solution untuk metode unggul pemberian sekelompok kemampuan menulis pengembang.

Solusi Standar

Jika Anda menempatkan semua pengembang di grup yang dibuat khusus, Anda dapat, pada prinsipnya, lakukan saja:

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

Kemudian ubah umaskuntuk pengguna 002, sehingga file baru dapat dibuat dengan izin grup-bisa ditulis.

Masalah dengan ini adalah legiun; jika Anda berada di sebuah distro yang mengasumsikan umaskdari 022(seperti memiliki umum userskelompok yang mencakup semua orang secara default), ini dapat membuka masalah keamanan di tempat lain. Dan cepat atau lambat, sesuatu akan mengacaukan skema izin Anda yang dibuat dengan hati-hati, membuat repo tidak aktif sampai Anda mendapatkan rootakses dan memperbaikinya (yaitu, menjalankan kembali perintah di atas).

Solusi Gelombang Baru

Solusi superior — meskipun kurang dipahami dengan baik, dan yang membutuhkan sedikit lebih banyak dukungan OS / alat — adalah dengan menggunakan atribut extended POSIX. Saya hanya datang ke daerah ini baru-baru ini, jadi pengetahuan saya di sini tidak sepanas mungkin. Tetapi pada dasarnya, ACL yang diperluas adalah kemampuan untuk mengatur izin pada lebih dari 3 slot default (pengguna / grup / lainnya).

Jadi sekali lagi, buat grup Anda, lalu jalankan:

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

Ini mengatur ACL yang diperluas untuk grup sehingga anggota grup dapat membaca / menulis / mengakses file apa pun yang sudah ada (baris pertama); kemudian, beri tahu semua direktori yang ada bahwa file baru harus memiliki ACL yang sama ini diterapkan (baris kedua).

Harapan yang membuat Anda di jalan.

womble
sumber
62
git init memiliki parameter bernama - Shared yang mengatur variabel core.sharedRepository untuk kerja kelompok. Anda juga dapat mengatur variabel pada repositori yang ada. Itu menghilangkan kebutuhan pengaturan umask secara manual sebagai git akan mengaturnya ke nilai waras sebelum memanipulasi file.
ptman
6
+1 untuk atribut diperluas POSIX - berita untuk saya!
RobM
5
Ketika saya melakukannya chmod -R g+swX, itu membuat Git sangat tidak senang dan memutuskan itu bukan repositori git lagi ("repo tampaknya bukan repositori git"). Saya harus chmod gs semua file . Untuk hanya mengatur bit setgid pada direktori , coba find /path/to/repo -type d -print0 | xargs -0 chmod g+s. Masih melakukan chgrp -R thegroup /path/to/repo.
rescdsk
10
chmod -R g+swX gitrepoakan menerapkan bit setguid ke file, yang merupakan risiko keamanan. Sebagai gantinya, Anda dapat menggunakannya find . -type d -exec chmod g+s {} +untuk menerapkannya hanya ke direktori.
Ian Dunn
1
ACL (setfacl) tidak memiliki pengaturan untuk setgid untuk memberlakukan file dan subdirektori baru yang dibuat dalam direktori untuk mewarisi ID grupnya. Oleh karena itu, Anda harus mengatur setgid secara terpisah melalui chmod. Namun, opsi - shared Git ( git-scm.com/docs/git-init ) memungkinkan Anda untuk mengatur gg dan menimpa umask pengguna.
Chase T.
121

jika Anda membuat repositori (atau mengkloning repo telanjang yang sudah ada) dengan

$ git init --shared=group 

atau

$ git init --shared=0NNN

Git seharusnya menangani izin di atas dan di luar apa yang disediakan umask default Anda. Akhirnya ini benar pada versi Git saya (1.6.3). Tentu saja ini mengasumsikan pengguna Anda berada di grup yang sama.

Namun, jika saya memerlukan manajemen pengguna dalam beberapa grup dengan berbagai tingkat baca / tulis, saya akan menggunakan gitosis. Saya juga pernah mendengar penyebutan gitolite ( http://github.com/sitaramc/gitolite ), garpu gitosis yang dibuat-buat untuk memberikan izin tingkat cabang, tidak bisa mengatakan bahwa saya setiap menggunakannya secara pribadi.

Rumah pantai
sumber
9
Ini jelas jawaban yang tepat.
ELLIOTTCABLE
4
Saya memiliki masalah ini dan sejauh ini merupakan jawaban terbaik. Satu-satunya masalah adalah bahwa --sharedargumen mengambil oktal, bukan heksadesimal. Saya telah mengkonfirmasi ini di sumber Git 1.7.8 dan contoh kedua seharusnya git init --shared=0NNN.
qpingu
3
Apa itu NNN— topeng misi atau nomor grup atau yang lainnya?
Craig McQueen
20
BTW, "grup" di atas adalah kata kunci, bukan pengganti untuk nama grup Anda. Anda menetapkan grup menggunakan perintah chgrp. Untuk repo baru, ini adalah git init --bare --shared=group myprojtempat myproj adalah nama repo Anda, diikuti dengan di chgrp -R mygroup myprojmana mygroup adalah nama grup Anda.
labradort
2
Perlu diketahui bahwa jika pengguna Anda membuat komitmen ketika grup default mereka berbeda dari yang seharusnya, itu dapat mengacaukan segalanya. Untuk memperbaiki masalah ini, Anda perlu setiap pengguna untuk chgrp setiap file yang mereka miliki di repo ke grup yang tepat. Ini akan berulang kecuali jika Anda mengetahui cara membuat semua orang membuat / mengalihkan file baru di bawah / ke grup yang tepat sebelum melakukan dan mendorong.
ragerdl
55

Ini belum dikatakan, jadi saya ingin segera menambahkannya.

Untuk memastikan bahwa masalah izin tidak memotong kepala jeleknya, pastikan untuk mengatur yang berikut ini di file konfigurasi repositori git Anda yang dibagikan:

[core]
    sharedRepository = true

Ini akan memastikan bahwa pengaturan "umask" sistem Anda dihormati.

Niels Joubert
sumber
6
Menurut git-config (1) ( kernel.org/pub/software/scm/git/docs/git-config.html ) core.shareRepository, Anda perlu mengatur ini ke "umask" atau "false" untuk memiliki rasa hormat git umask pengguna.
David Schmitt
14
Ini dan jawaban user35117 benar. Perhatikan bahwa "true" sama dengan "grup", dan ini dapat diatur dengan perintah git config core.sharedRepository true.
ColinM
Apakah masih mengubah kepemilikan file ketika didorong ke remote?
Duc Tran
2
Jika Anda ingin mengatur ini saat kloning daripada setelah fakta, padanannya git init --sharedadalah git clone --config core.sharedRepository=true. Strange of git digunakan --shareduntuk arti yang berbeda seperti itu dalam perintah yang serupa.
stevek_mcc
21

The Git User Manual menjelaskan cara berbagi repositori dalam beberapa cara.

Lebih rumit, meskipun fitur penuh fitur untuk berbagi repositori adalah:

Kami menggunakan GitHub untuk tim yang terdiri dari 6 pengembang.

jtimberman
sumber
1
Saya suka Gitosis. Ini cara yang cukup efektif untuk mengontrol akses berdasarkan kunci publik.
Mike Mazur
Bagaimana salah satu solusi ini memecahkan masalah "Saya ingin banyak orang menarik ke repositori itu"?
womble
lihatlah gitosis. yang memecahkan masalah Anda.
pilif
3
Saat Anda membagikan repositori, orang-orang akan dapat menarik darinya. Mereka mungkin perlu mengkloningnya, atau menambahkan cabang jarak jauh. Dokumentasi yang saya tautkan akan dengan sangat jelas memandu Anda menyelesaikan masalah Anda; Saya telah menggunakan semua metode yang dijelaskan untuk membantu pengembang berkolaborasi dengan kode sumber dengan Git. Sepengetahuan saya ServerFault bukan untuk pegangan.
jtimberman
3
Saya harus setuju dengan penggunaan Gitosis. Ini mengatasi masalah izin dengan menggunakan satu akun yang diautentikasi oleh beberapa kunci SSH. Ia juga dikelola sepenuhnya sendiri melalui git commit.
Jeremy Bouse
9

Lihat juga gitolite untuk hosting repositori git Anda. Gitosis tampaknya tidak dikembangkan lagi.

mt3
sumber
4

Salah satu cara untuk memperbaiki izin dalam repositori bersama, sehingga pengguna tidak akan memiliki masalah izin saat mendorong, adalah dengan membuat skrip kait pasca-pembaruan yang akan melakukan hal itu. Ini harus bekerja di semua versi git.

Misalkan Anda memiliki repositori bersama di / myrepo.git. Semua file di repositori itu milik mengatakan mysharegroup . Semua pengguna yang mendorong ke repositori itu juga harus menjadi anggota grup berbagi saya . Sekarang buat file berikut (ubah my sharedgroup ke preferensi Anda):

/myrepo.git/hooks/post-update

#!/bin/sh
chmod -R g+w . 2>/dev/null
chgrp -R mysharedgroup . 2>/dev/null
bkmks
sumber
jawaban yang tepat ketika pengguna memiliki grup default yang berbeda
Pat
Mengatur bit setgid pada direktori akan menyebabkan file yang dibuat pengguna untuk mewarisi kepemilikan grup yang sama dengan direktori (jika pengguna termasuk dalam grup itu). Bahkan jika itu bukan grup default pengguna. Maka kait ini tidak diperlukan. Inilah yang dilakukan oleh jawaban @ womble (dan komentar saya tentang itu).
rescdsk
Pada mesin centos7 saya, setelah mencoba setiap solusi yang tercantum pada halaman ini, varian dari solusi @ bkmks di atas adalah satu-satunya pilihan yang benar-benar berfungsi (mengatur kait pasca-penggabungan dan pasca-checkout alih-alih pasca pembaruan seperti di atas).
Mike Godin
Saya pikir itu saran yang buruk untuk mempromosikan solusi yang mengirim pesan kesalahan atau peringatan pada STDER /dev/null. Biarkan pengguna melihat pesan-pesan ini terlebih dahulu dan kemudian memutuskan sendiri.
Daniel Böhmer
3

Untuk mengumpulkan sedikit demi sedikit saran bagus dari berbagai jawaban dan komentar lain tentang menyiapkan repo baru:

Jika Anda sedang menyiapkan merek repo baru myrepodi /srv/gituntuk grup mygroup, ini adalah apa yang Anda inginkan:

mkdir /srv/git/myrepo.git
chgrp mygroup /srv/git/myrepo.git
git init --bare --shared /srv/git/myrepo.git
  1. baris pertama membuat dir repo
  2. baris kedua mengatur grupnya menjadi mygroup
  3. baris ketiga menginisialisasi repo telanjang dengan konfigurasi berikut:
    1. core.bare = true: buat repo kosong
    2. core.sharedrepository = 1(Sama seperti core.sharedrepository = group): direktori repo dan semua direktori yang dibuat nanti di dalamnya akan dikelola oleh git untuk mengizinkan mygroupmembaca, menulis, dan mengeksekusi izin (dengan bit sgid diatur juga - sehingga dapat bekerja dengan pengguna yang mygroupbukan milik mereka. grup utama)
    3. receive.denyNonFastforwards = 1: deny non-forward fastes to the repo

Jika Anda ingin menyempurnakan izin pengguna, grup, atau pengguna lain, gunakan --shared=0NNN, di mana NNNpengguna standar, grup, dan bit lain untuk file (bit eksekusi dan bit pada direktori akan dikelola dengan tepat oleh git). Misalnya, ini memungkinkan akses baca dan tulis ke pengguna, dan akses hanya baca ke grup (dan tidak ada akses ke yang lain):

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

Ini memungkinkan akses baca dan tulis ke pengguna dan grup (dan tidak ada akses ke yang lain):

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

Ini memungkinkan akses baca dan tulis ke pengguna dan grup, dan akses hanya baca ke yang lain:

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

Perhatikan bahwa jika Anda tidak akan mengizinkan akses tulis ke grup, pastikan untuk pertama kali menggunakan chownuntuk mengatur pemilik repo, dan kemudian jalankan git initperintah sebagai pengguna (untuk memastikan repo diinisialisasi dengan pemilik yang benar untuk semua file awal dan sub-direktori).

Justin Ludwig
sumber
Lebih benar daripada respons suara yang lebih tinggi.
XO01
1

Melakukan hal ini bekerja untuk saya, untuk repositori yang ada. Ini membutuhkan saran dari beberapa jawaban dan komentar sebelumnya:

Dari direktori induk repositori Anda, di 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
sumber
0

@stevek_mcc jawaban adalah yang saya cari ketika saya mencari pertanyaan ini di Google

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