อะไร - ปฏิบัติจริง - ความแตกต่างระหว่างพื้นที่เก็บข้อมูลเปลือยและที่ไม่ใช่เปลือย?


213

ฉันได้อ่านเกี่ยวกับ repositores ที่เป็นค่าเริ่มต้นและไม่เปลือยใน Git แล้ว ฉันไม่สามารถเข้าใจได้ค่อนข้างดี (ในทางทฤษฎี) เกี่ยวกับความแตกต่างระหว่างพวกเขาและทำไมฉันควร "ดัน" ไปยังที่เก็บเปลือย นี่คือข้อตกลง:

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

ฉันเดาว่าต้นไม้ทำงานเก็บข้อมูลการกระทำสาขา ฯลฯ จากโครงการ ที่จะไม่ปรากฏใน repo เปลือย ดังนั้นจึงเป็นการดีกว่าสำหรับฉันที่จะ "ผลักดัน" ความมุ่งมั่นที่จะซื้อคืนต้นไม้ทำงาน

จากนั้นทำไมฉันจึงควรใช้ที่เก็บเปลือยและทำไมไม่ ความแตกต่างในทางปฏิบัติคืออะไร นั่นจะไม่เป็นประโยชน์กับคนที่ทำงานในโครงการฉันคิดว่า

คุณมีวิธีการอย่างไรสำหรับงานประเภทนี้? ข้อเสนอแนะ?


4
AeroCross คุณสามารถโคลนที่เก็บเปลือยเพื่อสร้างพื้นที่เก็บข้อมูลที่ไม่ได้เปลือยเปล่า (นั่นคือหนึ่งซึ่งมีพื้นที่ทำงาน) ดังนั้นการใช้git cloneคุณสามารถแปลงระหว่างที่เก็บข้อมูลเปลือยและที่ไม่ใช่ข้อมูลเปลือยได้อย่างอิสระ
Derek Mahar

13
@ AeroCross: มันไม่เกี่ยวกับการแปลง; ไม่สำคัญว่าอะไรจะเกิดขึ้น หากคุณเรียกใช้git clone --bareคุณจะได้รับ repo เปล่าและถ้าคุณเรียกใช้git cloneคุณจะได้รับrepo เปลือย ทุกโครงการสาธารณะที่คุณเคยโคลน (โฮสต์บน Github เป็นต้น) เป็นพื้นที่เก็บข้อมูลเปล่าที่ส่วนอื่น ๆ
Cascabel

1
Jefromi ฉันแก้ไขจุด AeroCross '"ดังนั้นถ้าฉันลอกโคลน repo ฉันจะไม่มี" ต้นไม้ทำงาน "" ดังนั้นมันจึงเป็นการแปลง และไม่ใช่ทุกโครงการสาธารณะจะต้องเป็นพื้นที่เก็บข้อมูลเปลือย เป็นเพียงตัวเลือกทั่วไปเนื่องจากพื้นที่เก็บข้อมูลเปล่ามีประสิทธิภาพมากกว่าเนื่องจากไม่มีต้นไม้ทำงาน (เป็นพื้นที่ที่มีประสิทธิภาพเท่ากับพื้นที่เก็บข้อมูลใด ๆ ที่ไม่มีต้นไม้ทำงาน)
Derek Mahar

2
@ ดีเร็ก: แต่ประเด็นก็คือทันทีที่พบไดเร็กตอรี่. git การดึงข้อมูลจะไม่ทราบว่ารีโมตนั้นเปลือยเปล่าหรือไม่ มันไม่ได้แปลง มันดึงสิ่งที่ต้องการจากรีโมตและนำไปไว้ในที่ที่ควรไป ไม่มีอะไรจะแปลง นั่นคือสิ่งที่ฉันพยายามจะเน้นไปที่ OP และฉันก็ทราบดีว่าโครงการสาธารณะไม่จำเป็นต้องเปลือยเปล่า แต่เนื่องจากคนไม่โง่พวกเขาทั้งหมดล้วนเป็น ฉันคิดว่าฉันทำหลักเกณฑ์ทั่วไปที่ยอมรับได้
Cascabel

2
ดูที่Push to non-bare repositoryซึ่งให้คำอธิบายที่ยอดเยี่ยมอีกประการหนึ่งเกี่ยวกับการใช้ที่เก็บเปลือย
Craig McQueen

คำตอบ:


95

ข้อแตกต่างอื่น ๆ ระหว่างที่เก็บเปลือยและที่ไม่ใช่เปลือยคือที่เก็บเปลือยไม่มีที่เก็บข้อมูลต้นทางแบบเริ่มต้น :

~/Projects$ git clone --bare test bare
Initialized empty Git repository in /home/derek/Projects/bare/
~/Projects$ cd bare
~/Projects/bare$ git branch -a
* master
~/Projects/bare$ cd ..
~/Projects$ git clone test non-bare
Initialized empty Git repository in /home/derek/Projects/non-bare/.git/
~/Projects$ cd non-bare
~/Projects/non-bare$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

จากหน้าคู่มือสำหรับgit clone --bare:

ส่วนหัวสาขาที่รีโมตจะถูกคัดลอกโดยตรงไปยังหัวสาขาโลคัลที่สอดคล้องกันโดยไม่ต้องแม็พกับรีโมต / remotes / origin / เมื่อใช้ตัวเลือกนี้จะไม่มีการสร้างสาขาการติดตามระยะไกลหรือตัวแปรการกำหนดค่าที่เกี่ยวข้อง

สันนิษฐานว่าเมื่อมันสร้างที่เก็บเปลือย Git สันนิษฐานว่าที่เก็บเปลือยจะทำหน้าที่เป็นที่เก็บต้นทางสำหรับผู้ใช้ระยะไกลหลายคนดังนั้นจึงไม่ได้สร้างแหล่งกำเนิดระยะไกลเริ่มต้น สิ่งนี้หมายความว่าอะไรพื้นฐานgit pullและgit pushการดำเนินการจะไม่ทำงานเนื่องจาก Git สันนิษฐานว่าไม่มีพื้นที่ทำงานคุณไม่ต้องการกระทำการเปลี่ยนแปลงใด ๆ กับที่เก็บเปลือย:

~/Projects/bare$ git push
fatal: No destination configured to push to.
~/Projects/bare$ git pull
fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.
~/Projects/bare$ 

1
ใช่ฉันยอมรับว่านี่เป็นความแตกต่างที่สำคัญที่สุดระหว่างที่เก็บ Git เปลือยและไม่ใช่เปลือย ความจริงที่ว่าที่เก็บที่ไม่ได้เปลือยมีพื้นที่ทำงาน แต่ที่เก็บเปลือยไม่ได้เป็นความแตกต่างที่สำคัญ แต่git clone --no-checkoutสามารถสร้างที่เก็บที่ไม่ได้เปลือยด้วยที่ไม่มีไฟล์พื้นที่ทำงานได้เช่นกัน
Derek Mahar

10
พื้นที่เก็บข้อมูลที่ไม่ได้เปลือยไม่จำเป็นต้องมี "แหล่งกำเนิด" เริ่มต้นระยะไกลด้วยเช่นกัน
mipadi

2
คุณสามารถสร้างที่เก็บ Git ได้ง่ายๆด้วยgit initซึ่งจะสร้าง repo ที่ไม่ได้เปลือยโดยไม่ระบุระยะไกล
mipadi

1
mipadi นี่เป็นเรื่องจริง แต่ก็ไม่ได้เป็นโคลน
Derek Mahar

1
สิ่งนี้ไม่ถูกต้อง ที่เก็บจะมีต้นกำเนิดเริ่มต้นหากมีการcloneแก้ไข หากได้รับการinitแก้ไขในพื้นที่จะไม่มีต้นกำเนิดดังกล่าว สิ่งนี้ไม่เกี่ยวกับว่ามันจะเปลือยเปล่าหรือเปล่า
Noufal Ibrahim

62

ความแตกต่างระหว่างพื้นที่เก็บข้อมูล Git เปลือยและไม่เปลือยเป็นของปลอมและทำให้เข้าใจผิดเนื่องจากพื้นที่ทำงานไม่ได้เป็นส่วนหนึ่งของพื้นที่เก็บข้อมูลและพื้นที่เก็บข้อมูลไม่ต้องการพื้นที่ทำงาน พื้นที่เก็บข้อมูล Git พูดอย่างเคร่งครัดรวมถึงวัตถุเหล่านั้นที่อธิบายถึงสถานะของพื้นที่เก็บข้อมูล วัตถุเหล่านี้อาจมีอยู่ในไดเรกทอรีใด ๆ แต่โดยทั่วไปแล้วจะมีอยู่ใน.gitไดเรกทอรีในไดเรกทอรีระดับบนสุดของพื้นที่ทำงาน เวิร์กสเปซเป็นแผนผังไดเร็กทอรีที่แสดงถึงการคอมมิชชันเฉพาะในที่เก็บ แต่อาจมีอยู่ในไดเร็กทอรีใด ๆ หรือไม่เลย ตัวแปรสภาพแวดล้อม$GIT_DIRลิงก์พื้นที่ทำงานไปยังที่เก็บซึ่งมีต้นกำเนิด

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


61

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

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

60

5 ปีที่แล้วฉันรู้ แต่ไม่มีใครตอบคำถาม:

จากนั้นทำไมฉันจึงควรใช้ที่เก็บเปลือยและทำไมไม่ ความแตกต่างในทางปฏิบัติคืออะไร นั่นจะไม่เป็นประโยชน์กับคนที่ทำงานในโครงการมากขึ้นฉันคิดว่า

คุณมีวิธีการอย่างไรสำหรับงานประเภทนี้? ข้อเสนอแนะ?

หากต้องการอ้างอิงโดยตรงจากหนังสือ Loeliger / MCullough (978-1-449-31638-9, p196 / 7):

พื้นที่เก็บข้อมูลเปล่าอาจดูเหมือนจะใช้น้อย แต่บทบาทของมันมีความสำคัญ: เพื่อใช้เป็นจุดโฟกัสที่มีสิทธิ์สำหรับการพัฒนาความร่วมมือ ผู้พัฒนารายอื่นcloneและfetchจากที่เก็บเปลือยและpushอัปเดตเป็น ... หากคุณตั้งค่าที่เก็บที่ผู้พัฒนาpushเปลี่ยนแปลง ในกรณีนี้เป็นกรณีพิเศษของแนวปฏิบัติทั่วไปที่ดีกว่าที่ควรจะมีคลังเก็บที่เผยแพร่


19

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


นั่นหมายความว่าฉันสามารถเพิ่มสาขาแท็กและอื่น ๆ ในที่เก็บเปลือยจากนั้นดึงจากที่โล่งไปยังที่เก็บที่ไม่ได้เปลือย / ที่ผลิตได้
AeroCross

2
mipadi, พื้นที่เก็บข้อมูลที่ไม่ได้เปลือยอาจไม่มีแผนผังที่เช็คเอาท์ git clone --no-checkoutเป็นกรณีนี้ถ้าคุณสร้างพื้นที่เก็บข้อมูลที่ไม่ได้เปลือยด้วย ในกรณีนี้ที่เก็บที่ไม่ได้เปลือยมีที่ตั้งสำหรับพื้นที่ทำงาน แต่ Git ไม่ได้ชำระเงินไฟล์ใด ๆ ลงในพื้นที่ทำงานนั้น
Derek Mahar

17

พื้นที่เก็บข้อมูลเปล่ามีประโยชน์

  • ลดการใช้ดิสก์
  • ปัญหาที่เกี่ยวข้องกับการกดทางไกลน้อยลง (เนื่องจากไม่มีแผนผังการทำงานที่ต้องออกจากการซิงค์หรือมีการเปลี่ยนแปลงที่ขัดแย้งกัน)

3
ดังนั้นที่เก็บเปลือยเป็นวิธีที่ดีที่สุดในการทำงานกับหลาย ๆ คนที่ไม่สามารถเข้าถึงที่เก็บของพวกเขา? (kinda like SVN?)
AeroCross

2
AeroCross ฉันว่าพื้นที่เก็บข้อมูลเปล่าเป็นตัวเลือกที่ดีสำหรับสถานการณ์นั้น
Derek Mahar

12

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

ที่เก็บของเปลือยถูกเปลี่ยนโดยการขนส่งการเปลี่ยนแปลงจากที่เก็บอื่นเท่านั้น


10

ฉันไม่ใช่ผู้เชี่ยวชาญ "Git" แน่นอน ฉันเคยใช้ TortoiseGit มาระยะหนึ่งแล้วและสงสัยว่ามันกำลังพูดถึงอะไรเมื่อถามฉันว่าฉันต้องการสร้าง repo "เปลือย" เมื่อใดก็ตามที่ฉันสร้างขึ้นมา ฉันกำลังอ่านบทช่วยสอนนี้: https://www.atlassian.com/git/tutorials/setting-up-a-repository/git-initและแก้ไขปัญหา แต่ฉันก็ยังไม่ค่อยเข้าใจแนวคิด หนึ่งนี้ช่วยมาก: http://bitflop.com/tutorials/git-bare-vs-non-bare-repositories.html ตอนนี้คนแรกก็สมเหตุสมผลเช่นกัน!

ตามแหล่งข้อมูลเหล่านี้โดยย่อแล้ว repo "bare" ถูกใช้บนเซิร์ฟเวอร์ที่คุณต้องการตั้งค่าจุดแจกจ่าย มันไม่ได้มีไว้สำหรับใช้กับเครื่องท้องถิ่นของคุณ โดยทั่วไปแล้วคุณจะส่งคำสั่งจากเครื่องท้องถิ่นไปยัง repo เปล่าบนเซิร์ฟเวอร์ระยะไกลและคุณและ / หรือคนอื่น ๆ ดึงจาก repo เปล่านั้นไปยังเครื่องท้องถิ่นของคุณ ดังนั้น GitHub, Assembla ของคุณ ฯลฯ การเก็บข้อมูล / การกระจายระยะไกล repo เป็นตัวอย่างที่มีการสร้าง repo "เปลือย" ขึ้น คุณจะทำด้วยตัวเองถ้าคุณตั้ง "ศูนย์การแบ่งปัน" แบบอะนาล็อกของคุณเอง


ooooh ฉันเข้าใจแล้ว
Fuseteam

9

ค่าเริ่มต้น Git repo / ไม่เปลือยประกอบด้วยสถานะสองส่วน:

  1. แน็ปช็อตของไฟล์ทั้งหมดในที่เก็บ (นี่คือความหมายของ "แผนผังการทำงาน" ใน Git ศัพท์แสง)
  2. ประวัติความเป็นมาของการเปลี่ยนแปลงทั้งหมดที่เกิดขึ้นกับไฟล์ทั้งหมดที่เคยอยู่ในพื้นที่เก็บข้อมูล (ดูเหมือนจะไม่ชัดเจนว่าเป็นคำศัพท์เฉพาะของ Git ที่ครอบคลุมสิ่งเหล่านี้ทั้งหมด)

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

ประวัติศาสตร์เป็นรัฐที่ช่วยให้คุณตรวจสอบที่แตกต่างกันกระทำและได้รับภาพรวมที่สมบูรณ์ของสิ่งที่ไฟล์ในพื้นที่เก็บข้อมูลของคุณดูเหมือนว่าเมื่อกระทำถูกเพิ่มเข้ามา ประกอบด้วยโครงสร้างข้อมูลจำนวนมากที่อยู่ภายใน Git ซึ่งคุณอาจไม่เคยมีปฏิสัมพันธ์โดยตรง ที่สำคัญประวัติไม่เพียงแค่เก็บข้อมูลเมตา (เช่น "ผู้ใช้ U เพิ่มบรรทัดนี้จำนวนมากให้กับไฟล์ F ในเวลา T ซึ่งเป็นส่วนหนึ่งของ Commit C") แต่ยังเก็บข้อมูล (เช่น "ผู้ใช้ U เพิ่มบรรทัดที่แน่นอนเหล่านี้ลงในไฟล์ F" )

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

พื้นที่เก็บข้อมูลเปลือยเป็นพื้นที่เก็บข้อมูล Git ที่ไม่ได้มีภาพ มันเป็นเพียงการเก็บประวัติ

ทำไมคุณต้องการสิ่งนี้ ถ้าคุณเพียงแค่โต้ตอบกับไฟล์ของคุณโดยใช้ Git (นั่นคือคุณจะไม่แก้ไขไฟล์ของคุณโดยตรงหรือใช้เพื่อสร้างไฟล์ปฏิบัติการ) คุณสามารถประหยัดพื้นที่ได้ด้วยการไม่เก็บภาพรวมเอาไว้ โดยเฉพาะอย่างยิ่งถ้าคุณรักษา repo เวอร์ชันรวมไว้ที่เซิร์ฟเวอร์ (เช่นคุณกำลังโฮสต์ GitHub ของคุณเอง) เซิร์ฟเวอร์นั้นน่าจะมี repo เปล่า (คุณยังคงใช้ repo ที่ไม่ได้เปลือยบนของคุณ แม้ว่าเครื่องในท้องถิ่นเนื่องจากคุณอาจต้องการแก้ไขภาพรวมของคุณ)

หากคุณต้องการคำอธิบายเชิงลึกเพิ่มเติมของ repos เปลือยและอีกกรณีใช้ตัวอย่างฉันเขียนโพสต์บล็อกที่นี่: https://stegosaurusdormant.com/bare-git-repo/


4

นี่ไม่ใช่คำตอบใหม่ แต่ช่วยให้ฉันเข้าใจแง่มุมต่าง ๆ ของคำตอบข้างต้น (และมันมากเกินไปสำหรับความคิดเห็น)

ใช้ Git Bash เพียงลอง:

me@pc MINGW64 /c/Test
$ ls -al
total 16
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../

me@pc MINGW64 /c/Test
$ git init
Initialized empty Git repository in C:/Test/.git/

me@pc MINGW64 /c/Test (master)
$ ls -al
total 20
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 .git/

me@pc MINGW64 /c/Test (master)
$ cd .git

me@pc MINGW64 /c/Test/.git (GIT_DIR!)
$ ls -al
total 15
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 ../
-rw-r--r-- 1 myid 1049089 130 Apr  1 11:35 config
-rw-r--r-- 1 myid 1049089  73 Apr  1 11:35 description
-rw-r--r-- 1 myid 1049089  23 Apr  1 11:35 HEAD
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 hooks/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 info/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 objects/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 refs/

เหมือนกับgit --bare:

me@pc MINGW64 /c/Test
$ ls -al
total 16
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:36 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../

me@pc MINGW64 /c/Test
$ git init --bare
Initialized empty Git repository in C:/Test/

me@pc MINGW64 /c/Test (BARE:master)
$ ls -al
total 23
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 ./
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:11 ../
-rw-r--r-- 1 myid 1049089 104 Apr  1 11:36 config
-rw-r--r-- 1 myid 1049089  73 Apr  1 11:36 description
-rw-r--r-- 1 myid 1049089  23 Apr  1 11:36 HEAD
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 hooks/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 info/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 objects/

2

$ git help repository-layout

พื้นที่เก็บข้อมูล Git มีสองรสชาติแตกต่างกัน:

  • ไดเร็กทอรี. git ที่รูทของแผนผังการทำงาน
  • ไดเรกทอรี. git ที่เป็นพื้นที่เก็บข้อมูลเปลือย (เช่นไม่มีแผนผังการทำงานของตัวเอง) ซึ่งโดยทั่วไปจะใช้สำหรับการแลกเปลี่ยนประวัติกับผู้อื่นโดยการผลักดันเข้าไปในนั้นและดึงข้อมูลจากมัน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.