ฉันจะแชร์ที่เก็บ Git กับผู้ใช้หลายคนบนเครื่องได้อย่างไร


216

ฉันมีที่เก็บ Git บนเซิร์ฟเวอร์จัดเตรียมซึ่งนักพัฒนาหลายคนต้องสามารถดึงไปได้ git-initดูเหมือนว่าจะมีการตั้งค่าสถานะใกล้เคียงกับสิ่งที่ฉันกำลังมองหา: --sharedยกเว้นฉันต้องการให้หลาย ๆ คนดึงไปยังที่เก็บนั้นเช่นกัน git-clone's --sharedธงทำบางสิ่งที่แตกต่างอย่างสิ้นเชิง

วิธีที่ง่ายที่สุดในการเปลี่ยนการอนุญาตของพื้นที่เก็บข้อมูลที่มีอยู่คืออะไร?


ฉันใช้ "Github สำหรับ Windows" และสลับไปมาระหว่างสองบัญชี Github: stackoverflow.com/questions/18565876/…
Alisa

คำตอบ:


186

สิทธิ์เป็นศัตรูพืช

โดยทั่วไปคุณต้องตรวจสอบให้แน่ใจว่านักพัฒนาเหล่านั้นสามารถเขียนถึงทุกอย่างใน repo คอมไพล์ได้

ข้ามไปที่โซลูชันคลื่นลูกใหม่สำหรับวิธีการที่เหนือกว่าในการให้ความสามารถในการเขียนแก่กลุ่มนักพัฒนาซอฟต์แวร์

โซลูชันมาตรฐาน

หากคุณให้นักพัฒนาทั้งหมดในกลุ่มที่สร้างขึ้นเป็นพิเศษคุณสามารถทำได้โดยหลักการ:

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

จากนั้นเปลี่ยนค่าumaskสำหรับผู้ใช้เป็น002เพื่อให้ไฟล์ใหม่ถูกสร้างขึ้นด้วยสิทธิ์การเขียนกลุ่ม

ปัญหาเกี่ยวกับเรื่องนี้คือกองทัพ หากคุณอยู่ใน distro ที่ถือว่าเป็นumaskของ022(เช่นมีusersกลุ่มทั่วไปที่รวมทุกคนโดยค่าเริ่มต้น) สิ่งนี้สามารถเปิดปัญหาด้านความปลอดภัยที่อื่น และไม่ช้าก็เร็วมีบางอย่างกำลังจะทำให้เสียรูปแบบการอนุญาตที่สร้างขึ้นมาอย่างระมัดระวังวาง repo ออกจากการกระทำจนกว่าคุณจะrootสามารถเข้าถึงและแก้ไขได้ (เช่นเรียกใช้คำสั่งข้างต้นอีกครั้ง)

โซลูชั่นคลื่นลูกใหม่

โซลูชันที่เหนือกว่า - แม้ว่าจะเข้าใจน้อยกว่าและต้องการการสนับสนุนจาก OS / เครื่องมืออีกเล็กน้อย - คือการใช้แอตทริบิวต์เพิ่มเติมของ POSIX ฉันเพิ่งมาที่นี่เมื่อไม่นานมานี้ความรู้ของฉันที่นี่ไม่ร้อนเท่าที่ควร แต่โดยทั่วไป ACL ที่ขยายเพิ่มคือความสามารถในการตั้งค่าการอนุญาตให้ใช้มากกว่า 3 สล็อตเริ่มต้น (ผู้ใช้ / กลุ่ม / อื่น ๆ )

ดังนั้นอีกครั้งสร้างกลุ่มของคุณแล้วเรียกใช้:

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

ชุดนี้ตั้ง ACL แบบขยายสำหรับกลุ่มเพื่อให้สมาชิกกลุ่มสามารถอ่าน / เขียน / เข้าถึงไฟล์ใดก็ตามที่มีอยู่แล้ว (บรรทัดแรก) จากนั้นบอกไดเรกทอรีที่มีอยู่ทั้งหมดว่าไฟล์ใหม่ควรใช้ ACL เดียวกันนี้ (บรรทัดที่สอง)

หวังว่าคุณจะได้รับในทางของคุณ


62
git init มีพารามิเตอร์ชื่อ --shared ซึ่งตั้งค่าตัวแปร core.sharedRepository สำหรับงานกลุ่ม คุณยังสามารถตั้งค่าตัวแปรในที่เก็บข้อมูลที่มีอยู่ ที่ไม่จำเป็นต้องตั้งค่า umask ด้วยตนเองเนื่องจาก git จะตั้งค่าเป็น sane ก่อนจัดการไฟล์
ptman

6
+1 สำหรับแอตทริบิวต์เพิ่มเติมของ POSIX - ข่าวให้ฉัน!
RobM

5
เมื่อฉันทำchmod -R g+swXมันทำให้ Git ไม่มีความสุขและตัดสินใจว่ามันไม่ใช่ที่เก็บ Git อีกต่อไป ("repo ดูเหมือนจะไม่เป็นที่เก็บ Git") ผมต้อง GS chmod ทั้งหมดของไฟล์ เพียงแค่ตั้งค่าบิต setgid ในไดเรกทอรีfind /path/to/repo -type d -print0 | xargs -0 chmod g+sลอง chgrp -R thegroup /path/to/repoยังคงทำ
rescdsk

10
chmod -R g+swX gitrepoจะใช้ setguid บิตกับไฟล์ซึ่งเป็นความเสี่ยงด้านความปลอดภัย แต่คุณสามารถใช้find . -type d -exec chmod g+s {} +เพื่อนำไปใช้กับไดเรกทอรีเท่านั้น
Ian Dunn

1
ACL (setfacl) ไม่มีการตั้งค่าสำหรับ setgid เพื่อบังคับใช้ไฟล์ใหม่และไดเรกทอรีย่อยที่สร้างขึ้นภายในไดเรกทอรีเพื่อรับรหัสกลุ่ม ดังนั้นคุณต้องตั้ง setgid แยกผ่าน chmod อย่างไรก็ตาม Git's - option options ( git-scm.com/docs/git-init ) ช่วยให้คุณสามารถตั้งค่าและแทนที่ umask ของผู้ใช้
Chase T.

121

หากคุณสร้างที่เก็บ (หรือโคลน repo ใหม่ที่ปิดอยู่ที่มีอยู่) ด้วย

$ git init --shared=group 

หรือ

$ git init --shared=0NNN

Git นั้นควรจัดการกับการอนุญาตด้านบนและเหนือสิ่งที่ umask เริ่มต้นของคุณมีให้ ในที่สุดนี่เป็นเรื่องจริงใน Git รุ่นของฉัน (1.6.3) แน่นอนว่าผู้ใช้ของคุณอยู่ในกลุ่มเดียวกัน

ถ้าฉันต้องการการจัดการผู้ใช้ในหลายกลุ่มที่มีองศาการอ่าน / เขียนที่แตกต่างกันไปฉันก็จะมี gitosis ฉันเคยได้ยินการพูดถึง gitolite ( http://github.com/sitaramc/gitolite ) ส้อม gitosis ที่ถูกระงับเพื่อให้สิทธิ์ระดับสาขาไม่สามารถพูดได้ว่าฉันทุกคนใช้มันเป็นการส่วนตัว


9
นี่เป็นคำตอบที่ถูกต้องอย่างแน่นอน
ELLIOTTCABLE

4
ฉันมีปัญหานี้และนี่คือคำตอบที่ดีที่สุด ปัญหาเพียงอย่างเดียวคือการ--sharedโต้แย้งที่เกิดขึ้นในฐานแปดไม่ใช่เลขฐานสิบหก ฉันได้รับการยืนยันนี้ในแหล่งที่มาของ Git 1.7.8 git init --shared=0NNNและตัวอย่างที่สองที่ควรจะเป็น
qpingu

3
- NNNหน้ากากหน้าที่หรือหมายเลขกลุ่มหรืออย่างอื่นคืออะไร
Craig McQueen

20
BTW "กลุ่ม" ด้านบนเป็นคำหลักไม่ใช่ตัวยึดตำแหน่งสำหรับชื่อกลุ่มของคุณ คุณกำหนดกลุ่มโดยใช้คำสั่ง chgrp สำหรับ repo ใหม่มันคือgit init --bare --shared=group myprojตำแหน่งที่ myproj เป็นชื่อ repo ของคุณตามด้วยchgrp -R mygroup myprojที่ mygroup เป็นชื่อกลุ่มของคุณ
ลาบราดอร์

2
หัวขึ้นว่าถ้าผู้ใช้ของคุณกระทำเมื่อกลุ่มเริ่มต้นของพวกเขาแตกต่างจากสิ่งที่ควรจะเป็นพวกเขาสามารถกรูขึ้น ในการแก้ไขปัญหานี้คุณจะต้องให้ผู้ใช้แต่ละคนทำการ chgrp ทุกไฟล์ที่พวกเขามีใน repo ไปยังกลุ่มที่ถูกต้อง สิ่งนี้จะเกิดขึ้นอีกถ้าคุณไม่ทราบวิธีการทำให้ทุกคนสร้าง / สลับไฟล์ใหม่ภายใต้ / ไปยังกลุ่มที่ถูกต้องก่อนที่จะส่งและส่งข้อมูล
ragerdl

55

ยังไม่ได้พูดดังนั้นฉันต้องการเพิ่มอย่างรวดเร็ว

เพื่อให้แน่ใจว่าปัญหาเกี่ยวกับสิทธิ์ไม่ครอบตัดหัวน่าเกลียดตรวจสอบให้แน่ใจว่าได้ตั้งค่าต่อไปนี้ในไฟล์กำหนดค่าของที่เก็บของ git ที่แชร์:

[core]
    sharedRepository = true

สิ่งนี้จะช่วยให้มั่นใจได้ว่าการตั้งค่า "umask" ของระบบของคุณเป็นที่ยอมรับ


6
ตาม git-config (1) ( kernel.org/pub/software/scm/git/docs/git-config.html ) core.sharedRepository คุณต้องตั้งค่านี้เป็น "umask" หรือ "false" เพื่อให้มีความเคารพคอมไพล์ umask ของผู้ใช้
David Schmitt

14
คำตอบนี้และผู้ใช้ 35117 ถูกต้อง โปรดทราบว่า "จริง" เป็นเช่นเดียวกับ "กลุ่ม" git config core.sharedRepository trueและนี้สามารถตั้งค่าด้วยคำสั่ง
ColinM

มันยังคงเปลี่ยนความเป็นเจ้าของไฟล์เมื่อมันถูกผลักไปที่รีโมตหรือไม่?
Duc Tran

2
หากคุณต้องการตั้งค่านี้เมื่อโคลนมากกว่าหลังจากที่ความจริงเท่ากับเป็นgit init --shared git clone --config core.sharedRepository=truegit แปลก ๆ ที่ใช้--sharedสำหรับความหมายที่ต่างกันในคำสั่งที่คล้ายกัน
stevek_mcc

21

คู่มือการใช้งาน Gitอธิบายวิธีการแบ่งปันพื้นที่เก็บข้อมูลในหลายวิธี

มีความซับซ้อนมากขึ้นแม้ว่าจะใช้วิธีการร่วมกันอย่างเต็มรูปแบบของคุณสมบัติ:

เราใช้ GitHub สำหรับทีมนักพัฒนา 6 คน


1
ฉันชอบ Gitosis เป็นวิธีที่มีประสิทธิภาพในการควบคุมการเข้าถึงโดยใช้คีย์สาธารณะ
Mike Mazur

วิธีแก้ไขปัญหาใด ๆ เหล่านี้แก้ปัญหา "ฉันต้องการให้หลายคนดึงไปที่ที่เก็บ"
womble

ลองดูที่ gitosis ที่แก้ปัญหาของคุณ
pilif

3
เมื่อคุณแชร์ที่เก็บคนจะสามารถดึงจากที่เก็บได้ พวกเขาอาจจำเป็นต้องโคลนหรือเพิ่มสาขาระยะไกล เอกสารที่ฉันเชื่อมโยงจะนำคุณไปสู่การแก้ไขปัญหาของคุณอย่างชัดเจน ฉันใช้วิธีการทั้งหมดที่อธิบายไว้เพื่อช่วยให้นักพัฒนาทำงานร่วมกันซอร์สโค้ดกับ Git เพื่อความรู้ของฉัน ServerFault ไม่ได้สำหรับการจับ
jtimberman

3
ฉันต้องเห็นด้วยกับการใช้ Gitosis มันได้รับการแก้ไขปัญหาการอนุญาตโดยใช้บัญชีเดียวรับรองความถูกต้องโดยคีย์ SSH หลาย ๆ นอกจากนี้ยังมีการจัดการทั้งหมดเองผ่านคอมมิทคอม
Jeremy Bouse

9

ดูgitoliteสำหรับโฮสต์ที่เก็บ git ของคุณ Gitosis ไม่ได้รับการพัฒนาอีกต่อไป


4

วิธีหนึ่งในการแก้ไขการอนุญาตในพื้นที่เก็บข้อมูลที่ใช้ร่วมกันดังนั้นผู้ใช้จะไม่มีปัญหาสิทธิ์เมื่อทำการพุชคือการสร้าง hook hook ของ post-update ซึ่งจะทำเช่นนั้น สิ่งนี้จะใช้ได้ในเวอร์ชัน git ใด ๆ

สมมติว่าคุณมีที่เก็บข้อมูลร่วมกันใน /myrepo.git ไฟล์ทั้งหมดในพื้นที่เก็บข้อมูลที่อยู่ที่จะพูดmysharedgroup ผู้ใช้ทั้งหมดผลักดันไปยังพื้นที่เก็บข้อมูลนั้นควรเป็นของmysharedgroupด้วย ตอนนี้สร้างไฟล์ต่อไปนี้ (เปลี่ยนmysharedgroupเป็นค่ากำหนดของคุณ):

/myrepo.git/hooks/post-update

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

คำตอบที่ถูกต้องเมื่อผู้ใช้มีกลุ่มเริ่มต้นแตกต่างกัน
Pat

การตั้งค่าบิต setgid ในไดเรกทอรีจะทำให้ไฟล์ที่ผู้ใช้สร้างเพื่อสืบทอดความเป็นเจ้าของกลุ่มเดียวกันกับไดเรกทอรี (หากผู้ใช้อยู่ในกลุ่มนั้น) แม้ว่าจะไม่ใช่กลุ่มเริ่มต้นของผู้ใช้ เบ็ดนี้ไม่จำเป็น นี่คือสิ่งที่คำตอบของ @ womble (และความคิดเห็นของฉันเกี่ยวกับเรื่องนี้) ทำ
rescdsk

บนเครื่อง centos7 ของฉันหลังจากลองทุกวิธีแก้ไขปัญหาที่ระบุไว้ในหน้านี้ตัวแปรของโซลูชันของ @ bkmks ด้านบนเป็นตัวเลือกเดียวที่ใช้งานได้จริง
Mike Godin

/dev/nullฉันคิดว่ามันเป็นคำแนะนำที่ดีที่จะส่งเสริมการแก้ปัญหาซึ่งข้อความผิดพลาดท่อหรือคำเตือนเกี่ยวกับการ STDER โปรดให้ผู้ใช้เห็นข้อความเหล่านี้ก่อนแล้วจึงตัดสินใจด้วยตัวเอง
Daniel Böhmer

3

ในการรวมบิตและชิ้นส่วนของคำแนะนำที่ดีจากคำตอบและความคิดเห็นอื่น ๆ เกี่ยวกับการตั้งค่า repo ใหม่:

หากคุณกำลังตั้งค่าแบรนด์ repo ใหม่myrepoใน/srv/gitกลุ่มmygroupนี้คือสิ่งที่คุณต้องการ:

mkdir /srv/git/myrepo.git
chgrp mygroup /srv/git/myrepo.git
git init --bare --shared /srv/git/myrepo.git
  1. บรรทัดแรกสร้าง repo dir
  2. บรรทัดที่สองตั้งค่ากลุ่มเป็น mygroup
  3. บรรทัดที่สามเริ่มต้น repo เปล่าด้วยการกำหนดค่าต่อไปนี้:
    1. core.bare = true: ทำให้มันเป็น repo เปลือย
    2. core.sharedrepository = 1(เช่นเดียวกับcore.sharedrepository = group): ไดเรกทอรี repo และไดเรกทอรีทั้งหมดที่สร้างขึ้นในภายหลังจะได้รับการจัดการโดย git เพื่ออนุญาตการmygroupอ่านเขียนและเรียกใช้สิทธิ์ (ด้วยการตั้งค่าบิต sgid เช่นกัน - เพื่อทำงานกับผู้ใช้ที่mygroupไม่ใช่ของพวกเขา กลุ่มหลัก)
    3. receive.denyNonFastforwards = 1: ปฏิเสธการกดไปข้างหน้าอย่างเร็ว

หากคุณต้องการที่จะปรับสิทธิ์การใช้งานกลุ่มหรือผู้ใช้คนอื่นใช้--shared=0NNNที่NNNเป็นผู้ใช้มาตรฐานกลุ่มและบิตอื่น ๆ สำหรับไฟล์ (รันและบิต sgid ในไดเรกทอรีจะมีการจัดการอย่างเหมาะสมโดยคอมไพล์) ตัวอย่างเช่นสิ่งนี้อนุญาตให้เข้าถึงแบบอ่านและเขียนแก่ผู้ใช้และเข้าถึงแบบอ่านอย่างเดียวไปยังกลุ่ม (และไม่มีสิทธิ์เข้าถึงแบบอื่น):

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

สิ่งนี้อนุญาตให้ผู้ใช้และกลุ่มเข้าถึงแบบอ่านและเขียน (และไม่สามารถเข้าถึงแบบอื่น):

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

สิ่งนี้อนุญาตให้ผู้ใช้และกลุ่มเข้าถึงแบบอ่านและเขียนและเข้าถึงแบบอ่านอย่างเดียว:

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

โปรดทราบว่าหากคุณจะไม่อนุญาตให้มีการเข้าถึงการเขียนไปยังกลุ่มตรวจสอบให้แน่ใจว่าใช้งานครั้งแรกchownเพื่อตั้งเจ้าของ repo แล้วเรียกใช้git initคำสั่งในฐานะผู้ใช้นั้น (เพื่อให้แน่ใจว่า repo เริ่มต้นกับเจ้าของที่ถูกต้องสำหรับ ไฟล์เริ่มต้นและไดเรกทอรีย่อยทั้งหมด)


ถูกต้องมากกว่าคำตอบการโหวตที่สูงขึ้น
XO01

2

คุณสามารถใช้ git-daemon เพื่อแชร์ที่เก็บ อ่านเอกสารสำหรับgit-daemonสำหรับข้อมูลเพิ่มเติม

แก้ไข:

นอกจากนี้ตรวจสอบบทความนี้8 วิธีในการใช้พื้นที่เก็บข้อมูลคอมไพล์ของคุณ


1

การทำเช่นนี้ทำงานได้ดีสำหรับฉันสำหรับพื้นที่เก็บข้อมูลที่มีอยู่ สิ่งนี้จะได้รับคำแนะนำจากคำตอบและความคิดเห็นต่าง ๆ ก่อน:

จากไดเร็กทอรีพาเรนต์ที่เก็บของคุณที่เซิร์ฟเวอร์:

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 คำตอบคือสิ่งที่ฉันกำลังมองหาเมื่อฉัน googled สำหรับคำถามนี้

git clone --config core.sharedRepository=true
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.