อะไรคือความแตกต่างระหว่าง“ git init” และ“ git init --bare”?


162

ความแตกต่างระหว่างgit initและgit init --bareคืออะไร? ฉันพบว่าการโพสต์บล็อกจำนวนมากต้องการ--bareเซิร์ฟเวอร์ Git หรือไม่

จากหน้าคนก็กล่าวว่า:

--bare

สร้างพื้นที่เก็บข้อมูลเปล่า หากไม่ได้ตั้งค่าสภาพแวดล้อม GIT_DIR มันจะถูกตั้งค่าเป็นไดเรกทอรีการทำงานปัจจุบัน

แต่จริงๆแล้วมันหมายถึงอะไร? จำเป็นต้องมี--bareสำหรับการตั้งค่าเซิร์ฟเวอร์ Git หรือไม่

คำตอบ:


143

Repo Non-Bare Git

ตัวแปรนี้สร้างที่เก็บพร้อมไดเรกทอรีการทำงานเพื่อให้คุณสามารถทำงานได้จริง ( git clone) หลังจากสร้างมันคุณจะเห็นว่าไดเรกทอรีมีโฟลเดอร์. git ที่มีประวัติและการประปา git ทั้งหมดไป คุณทำงานในระดับที่โฟลเดอร์. git อยู่

Bare Git Repo

ชุดตัวเลือกอื่นจะสร้างที่เก็บโดยไม่มีไดเรกทอรีทำงาน ( git clone --bare) คุณไม่ได้รับไดเรกทอรีที่คุณสามารถทำงานได้ ทุกอย่างในไดเรกทอรีคือสิ่งที่อยู่ในโฟลเดอร์. git ในกรณีข้างต้น

ทำไมคุณถึงต้องใช้ One กับอันอื่น

ความต้องการ repos คอมไพล์ที่ไม่มีไดเร็คทอรี่สำหรับใช้ทำงานนั้นเป็นข้อเท็จจริงที่ว่าคุณสามารถผลักสาขาไปได้ คุณยังสามารถผลักดันไปยังที่เก็บที่ไม่ได้เปลือย แต่คุณจะถูกปฏิเสธเนื่องจากคุณสามารถย้ายสาขาที่มีคนทำงานอยู่ในไดเรกทอรีทำงานนั้น

ดังนั้นในโครงการที่ไม่มีโฟลเดอร์ที่ใช้งานได้คุณจะเห็นเฉพาะวัตถุที่คอมไพล์เก็บไว้เท่านั้น พวกเขาจะถูกบีบอัดและต่อเนื่องและจัดเก็บภายใต้ SHA1 (แฮช) ของเนื้อหา ในการรับวัตถุในที่เก็บเปลือยคุณต้องgit showระบุ sha1 ของวัตถุที่คุณต้องการดู คุณจะไม่เห็นโครงสร้างแบบโครงการของคุณ

ที่เก็บเปลือยมักเป็นที่เก็บส่วนกลางที่ทุกคนย้ายไปทำงาน ไม่จำเป็นต้องจัดการกับงานจริง เป็นวิธีการประสานความพยายามระหว่างคนหลายคน คุณจะไม่สามารถดูไฟล์โครงการของคุณโดยตรง

คุณอาจไม่จำเป็นต้องมีที่เก็บเปลือยใด ๆ หากคุณเป็นคนเดียวที่ทำงานในโครงการหรือคุณไม่ต้องการ / ต้องการพื้นที่เก็บข้อมูล "ศูนย์กลางตรรกะ" หนึ่งจะชอบgit pull จากที่เก็บอื่น ๆ ในกรณีนั้น สิ่งนี้จะหลีกเลี่ยงการคัดค้านที่คอมไพล์มีเมื่อผลักไปยังที่เก็บที่ไม่ได้เปลือย

หวังว่านี่จะช่วยได้


เก็บโยนออกจากบรรทัดนี้ - หนึ่งต้องการดึงคอมไพล์จากอื่น ๆ ... :-)
Arup Rakshit

10
ฉันพบว่าคำตอบนี้ไม่ชัดเจนและสับสนมาก เหตุผลบางประการอยู่ที่นี่: meta.stackoverflow.com/questions/339837/…
Marko Avlijaš

Bare repositories are usually central repositories where everyone moves their work to.คุณหมายถึงว่าพื้นที่เก็บข้อมูลเปล่าเป็นแหล่งที่ผู้ทำงานร่วมโครงการรายอื่นสามารถโคลนโครงการได้หรือไม่ นั่นคือผู้ทำงานร่วมกันปฏิบัติต่อสิ่งนี้ว่าเป็นremote?
Minh Tran

112

คำตอบสั้น ๆ

ที่เก็บเปลือยคือที่เก็บ git ที่ไม่มีสำเนาที่ใช้งานได้ดังนั้นเนื้อหาของ. git นั้นอยู่ระดับบนสุดสำหรับไดเรกทอรีนั้น

ใช้ที่เก็บที่ไม่ได้เปลือยเพื่อทำงานในพื้นที่และที่เก็บเปล่าเป็นเซิร์ฟเวอร์กลาง / ฮับเพื่อแชร์การเปลี่ยนแปลงของคุณกับผู้อื่น ตัวอย่างเช่นเมื่อคุณสร้างที่เก็บบน github.com มันจะถูกสร้างขึ้นเป็นที่เก็บเปลือย

ดังนั้นในคอมพิวเตอร์ของคุณ:

git init
touch README
git add README
git commit -m "initial commit"

บนเซิร์ฟเวอร์:

cd /srv/git/project
git init --bare

จากนั้นให้ลูกค้ากด:

git push username@server:/srv/git/project master

จากนั้นคุณสามารถบันทึกการพิมพ์ด้วยตัวเองโดยเพิ่มเป็นระยะไกล

ที่เก็บบนฝั่งเซิร์ฟเวอร์กำลังรับการคอมมิตผ่าน pull และ push และไม่ใช่โดยคุณแก้ไขไฟล์จากนั้นคอมมิทในเครื่องเซิร์ฟเวอร์ดังนั้นจึงเป็นที่เก็บเปลือย

รายละเอียด

คุณสามารถพุชไปยังที่เก็บที่ไม่ใช่ที่เก็บเปล่าและ git จะพบว่ามีที่เก็บ. git อยู่ที่นั่น แต่เนื่องจากที่เก็บ "ฮับ" ส่วนใหญ่ไม่ต้องการสำเนาที่ใช้งานได้จึงเป็นเรื่องปกติที่จะใช้ที่เก็บเปลือยสำหรับ มันและแนะนำเนื่องจากไม่มีจุดในการมีสำเนาการทำงานในที่เก็บชนิดนี้

อย่างไรก็ตามหากคุณกดไปยังที่เก็บที่ไม่มีการปิดบังคุณกำลังสร้างสำเนาการทำงานที่ไม่สอดคล้องกันและ git จะเตือนคุณ:

remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.

คุณสามารถข้ามคำเตือนนี้ได้ แต่การตั้งค่าที่แนะนำคือ: ใช้พื้นที่เก็บข้อมูลที่ไม่เปลือยเพื่อทำงานในพื้นที่และพื้นที่เก็บข้อมูลเปลือยเป็นฮับหรือเซิร์ฟเวอร์กลางที่จะผลักดันและดึงจาก

หากคุณต้องการแบ่งปันงานโดยตรงกับสำเนาการทำงานของนักพัฒนาคนอื่นคุณสามารถดึงที่เก็บซึ่งกันและกันแทนการพุช


ถ้าฉันต้องการทำงานโครงการของฉันบนเซิร์ฟเวอร์ git ดังนั้นจึงไม่จำเป็นต้องมีตัวเลือก --bare ใช่ไหม?
Kit Ho

คุณใช้เปล่าสำหรับที่เก็บระยะไกลไม่ใช่สำหรับที่เก็บในท้องถิ่น
แคน

มันเป็นเพียงเล็กน้อย แต่ที่นี่คำถามอื่น หากเรามีพื้นที่เก็บข้อมูลแบบรีโมตเปล่า ๆ ผู้พัฒนาสามารถดึงไปได้เลยพื้นที่เก็บข้อมูลคือ "ศูนย์กลาง" แต่ถ้าเราทำงานโดยไม่มีที่เก็บเปลือยนักพัฒนาควรดึงจากกัน แต่ไม่เคยดัน สถานการณ์สุดท้ายนั้นดีมากหากมีสำเนาการทำงานของ repo เพียง 2 สำเนาเท่านั้น (aka repos ภายในเครื่อง) ถูกต้องหรือไม่
Asturio

60

เมื่อฉันอ่านคำถามนี้เมื่อไม่นานมานี้ทุกสิ่งทำให้ฉันสับสน ฉันเพิ่งเริ่มใช้ git และมีสำเนาการทำงานเหล่านี้ (ซึ่งไม่มีความหมายในเวลานั้น) ฉันจะพยายามอธิบายเรื่องนี้จากมุมมองของคนที่เพิ่งเริ่มคอมไพล์โดยไม่มีความคิดเกี่ยวกับคำศัพท์

ตัวอย่างที่ดีของความแตกต่างสามารถอธิบายได้ด้วยวิธีต่อไปนี้ :

--bareให้คุณเป็นเพียงที่เก็บของ (คุณไม่สามารถพัฒนาได้) หากไม่มี--bareมันจะทำให้คุณสามารถพัฒนาได้ (และมีที่เก็บข้อมูล)

git initสร้างที่เก็บ git จากไดเรกทอรีปัจจุบันของคุณ มันเพิ่มโฟลเดอร์. git ข้างในและทำให้สามารถเริ่มต้นประวัติการแก้ไขของคุณได้

git init --bareยังสร้างที่เก็บ แต่ไม่มีไดเร็กทอรีที่ใช้งานได้ ซึ่งหมายความว่าคุณไม่สามารถแก้ไขไฟล์ส่งการเปลี่ยนแปลงเพิ่มไฟล์ใหม่ในที่เก็บได้

--bareจะมีประโยชน์เมื่อไหร่? คุณและคนอื่น ๆ กำลังทำงานในโครงการและใช้คอมไพล์ คุณโฮสต์โครงการบนเซิร์ฟเวอร์บางตัว ( amazon ec2) ec2แต่ละท่านมีเครื่องของคุณเองและคุณกดรหัสของคุณบน ไม่มีใครในคุณพัฒนาอะไรเลยec2(คุณใช้เครื่องของคุณ) - คุณแค่กดรหัส ดังนั้นคุณจึงec2เป็นเพียงที่เก็บข้อมูลสำหรับรหัสทั้งหมดของคุณและควรสร้างเป็น--bareและทุกเครื่องของคุณโดยไม่--bare(ส่วนใหญ่อาจเป็นเพียงหนึ่งและอื่น ๆ ที่จะโคลนทุกอย่าง) เวิร์กโฟลว์มีลักษณะดังนี้:

ป้อนคำอธิบายรูปภาพที่นี่


1
ดังนั้นเราสามารถพูดได้ว่าโดยการใช้พื้นที่เก็บข้อมูล --bare เราสามารถสร้างสถาปัตยกรรมไคลเอนต์ - เซิร์ฟเวอร์เช่นเดียวกับการโค่นล้ม?
Emiliano Sangoi

14

ที่เก็บ Git เริ่มต้นจะถือว่าคุณใช้เป็นไดเรกทอรีทำงานของคุณ โดยทั่วไปเมื่อคุณอยู่บนเซิร์ฟเวอร์คุณไม่จำเป็นต้องมีไดเรกทอรีทำงาน เพียงแค่แหล่งเก็บข้อมูล ในกรณีนี้คุณควรใช้--bareตัวเลือก


ใน repo ที่มี - ตัวเลือกเปลือยดังนั้นเราจึงไม่เห็นไฟล์โครงการทั้งหมด ดูเหมือนว่าฉันจะสูญเสียไฟล์โครงการทั้งหมดด้วย - ตัวเลือกเปลือย ..
Kit Ho

11

ที่เก็บที่ไม่ได้เปลือยเป็นค่าเริ่มต้น มันคือสิ่งที่ถูกสร้างขึ้นเมื่อคุณเรียกใช้git initหรือสิ่งที่คุณได้รับเมื่อคุณโคลน (โดยไม่มีbareตัวเลือก) จากเซิร์ฟเวอร์

เมื่อคุณทำงานกับที่เก็บเช่นนี้คุณสามารถดูและแก้ไขไฟล์ทั้งหมดที่อยู่ในที่เก็บ เมื่อคุณโต้ตอบกับพื้นที่เก็บข้อมูล - ตัวอย่างเช่นโดยการกระทำการเปลี่ยนแปลง - Git .gitเก็บการเปลี่ยนแปลงของคุณในไดเรกทอรีที่ซ่อนอยู่เรียกว่า

เมื่อคุณมีเซิร์ฟเวอร์คอมไพล์คุณไม่จำเป็นต้องทำการสำเนาไฟล์ เพียงคุณมีข้อมูล Git ที่เก็บไว้.gitที่เก็บไว้ใน พื้นที่เก็บข้อมูลเปล่าเป็น.gitไดเรกทอรีตรงโดยไม่มีพื้นที่ทำงานสำหรับการแก้ไขและกระทำไฟล์

เมื่อคุณโคลนจากเซิร์ฟเวอร์ Git มีข้อมูลทั้งหมดที่จำเป็นใน.gitไดเรกทอรีเพื่อสร้างสำเนาการทำงานของคุณ


1

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

ฉันสร้างพื้นที่เก็บข้อมูลครั้งแรก (ชื่อ: คอมไพล์เปลือย ) git init --bareด้วย มันเป็นเซิร์ฟเวอร์ มันอยู่ทางด้านซ้ายซึ่งไม่มีสาขาระยะไกลเพราะนี่คือที่เก็บของรีโมต

ฉันสร้างพื้นที่เก็บข้อมูลที่สอง (ชื่อ: git-Working-tree ) ด้วยgit cloneจากแรก มันอยู่ทางขวา มันมีสาขาท้องถิ่นเชื่อมโยงกับสาขาระยะไกล

(ข้อความ 'แรก', 'สอง', 'สาม', 'สี่', 'อัลฟ่า', 'เบต้า' และ 'เดลต้า' เป็นความคิดเห็นที่กระทำชื่อ 'เจ้านาย' และ 'กรีก' เป็นชื่อสาขา)

ที่เก็บข้อมูลโลคัลและรีโมต

ตอนนี้ผมจะลบสาขาชื่อว่า 'กรีกทั้งในคอมไพล์เปลือย (คำสั่งgit push --delete origin greek) และประเทศในคอมไพล์ทำงานต้นไม้ (คำสั่งgit branch -D greek) นี่คือลักษณะของต้นไม้:

พื้นที่เก็บข้อมูล git-bare ลบสิ่งที่ไม่มีการอ้างอิงอีกต่อไป

git-bareลบทั้งสาขาและ comits ที่อ้างอิงทั้งหมด ในภาพเราเห็นว่าต้นไม้ของมันลดลงด้วยเหตุนี้

ในขณะที่ต้นไม้คอมไพล์ทำงานซึ่งเทียบเท่ากับพื้นที่เก็บข้อมูลที่ใช้กันทั่วไปไม่ได้ลบ commits ซึ่งตอนนี้สามารถอ้างอิงได้โดยตรงโดยแฮชของคุณด้วยgit checkout 7fa897b7คำสั่ง นั่นคือเหตุผลที่ต้นไม้ของมันไม่มีโครงสร้างที่ปรับเปลี่ยน

โดยสังเขป: ความมุ่งมั่นจะไม่ตกอยู่ในที่เก็บต้นไม้ทำงานแต่จะถูกลบทิ้งในที่โล่งเก็บ

ในแง่การปฏิบัติคุณสามารถกู้คืนสาขาที่ถูกลบบนเซิร์ฟเวอร์หากมีอยู่ในที่เก็บในเครื่องเท่านั้น

แต่มันแปลกมากที่ขนาดของพื้นที่เก็บข้อมูลเปล่าไม่ลดลงขนาดดิสก์หลังจากลบสาขาระยะไกล นั่นคือไฟล์ยังคงมีอย่างใด เมื่อต้องการดัมพ์ที่เก็บโดยการลบสิ่งที่ไม่มีการอ้างอิงอีกต่อไปหรือสิ่งที่ไม่สามารถอ้างอิงได้ (กรณีหลัง) ใช้git gc --pruneคำสั่ง


หากต้องการทดสอบคำสั่ง git ให้ลอง: github.com/sergiocabral/App.GitPlayground
Sergio Cabral
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.