ความแตกต่างระหว่าง git clone --mirror และ git clone --bare


486

หน้าช่วยเหลือของ git clone มีสิ่งนี้เพื่อพูดเกี่ยวกับ--mirror:

ตั้งค่ามิเรอร์ของที่เก็บรีโมต --bareนี้มีความหมาย

แต่อย่าพูดถึงรายละเอียดว่า--mirrorโคลนแตกต่างจาก--bareโคลนอย่างไร


3
มีประโยชน์ แต่ถ้าคุณต้องการผลักมิเรอร์นี้ไปยัง repo ระยะไกลอย่าง Github ฉันก็พบว่าลิงค์นี้มีประโยชน์
กินที่ Joes

คำตอบ:


569

ความแตกต่างคือว่าเมื่อใช้--mirror, ทุก refs จะถูกคัดลอกตามที่เป็น ซึ่งหมายความว่าทุกอย่าง: สาขาการติดตามระยะไกล, บันทึกย่อ, refs / originals / * (สำรองจากตัวกรองสาขา) repo ที่ลอกเลียนแบบนั้นมีทั้งหมด นอกจากนี้ยังมีการตั้งค่าเพื่อให้การอัปเดตระยะไกลจะดึงข้อมูลทุกอย่างจากต้นทางอีกครั้ง (เขียนทับการอ้างอิงที่คัดลอก) แนวคิดนี้คือการทำมิเรอร์ที่เก็บจริงๆมีสำเนาทั้งหมดเพื่อให้คุณสามารถโฮสต์ repo ส่วนกลางของคุณในหลาย ๆ แห่งหรือสำรอง คิดว่าการคัดลอก repo เพียงแค่ตรงยกเว้นในวิธีคอมไพล์ที่หรูหรามากขึ้น

เอกสารใหม่บอกว่าทั้งหมดนี้สวยมาก:

--mirror

ตั้งค่ามิเรอร์ของแหล่งเก็บข้อมูลต้นฉบับ --bareนี้มีความหมาย เมื่อเทียบกับ--bare, --mirrorไม่เพียง แต่แผนที่สาขาในประเทศของแหล่งที่สาขาในประเทศเป้าหมายที่จะแผนที่ refs ทั้งหมด (รวมถึงสาขาระยะไกล, บันทึก ฯลฯ ) และตั้งค่าการกำหนดค่า refspec ดังกล่าวว่า refs ทั้งหมดเหล่านี้จะถูกเขียนทับโดยgit remote updateในพื้นที่เก็บข้อมูลเป้าหมาย .

คำตอบเดิมของฉันยังสังเกตเห็นความแตกต่างระหว่างโคลนเปลือยและโคลน (ไม่ใช่เปลือย) ปกติ - โคลนที่ไม่เปลือยตั้งสาขาติดตามระยะไกลเพียงสร้างสาขาท้องถิ่นสำหรับHEADในขณะที่โคลนโคลนคัดลอกสาขาโดยตรง

ต้นกำเนิดสมมติว่ามีกี่สาขา ( master (HEAD), next, puและmaint), แท็กบางคน ( v1, v2, v3) บางสาขาระยะไกล ( devA/master, devB/master) และบางส่วน refs อื่น ๆ ( refs/foo/bar, refs/foo/bazซึ่งอาจจะมีการบันทึก stashes, namespaces devs อื่น ๆ ที่รู้)

  • git clone origin-url(ไม่ใช่เปลือย):คุณจะได้รับแท็กทั้งหมดที่คัดลอกสาขาท้องถิ่นmaster (HEAD)ติดตามสาขาที่ห่างไกลorigin/masterและสาขาระยะไกลorigin/next, และorigin/pu origin/maintสาขาการติดตามได้รับการตั้งค่าเพื่อให้คุณทำสิ่งใดสิ่งgit fetch originหนึ่งสาขานั้นจะถูกดึงข้อมูลตามที่คุณคาดหวัง รีโมตสาขาใด ๆ (ในรีโมตที่โคลน) และการอ้างอิงอื่น ๆ จะถูกละเว้นอย่างสมบูรณ์

  • git clone --bare origin-url:คุณจะได้รับทั้งหมดของแท็กคัดลอกสาขาในประเทศmaster (HEAD), next, puและmaintสาขาระยะไกลไม่มีการติดตาม นั่นคือสาขาทั้งหมดจะถูกคัดลอกตามที่เป็นอยู่และตั้งค่าอย่างสมบูรณ์โดยไม่มีการดึงข้อมูลอีกครั้ง รีโมตสาขาใด ๆ (ในรีโมตที่โคลน) และการอ้างอิงอื่น ๆ จะถูกละเว้นอย่างสมบูรณ์

  • git clone --mirror origin-url:ทุก ๆ การอ้างอิงสุดท้ายจะถูกคัดลอกตามที่เป็นอยู่ คุณจะได้รับแท็กทุกสาขาในประเทศmaster (HEAD), next, puและmaintสาขาระยะไกลdevA/masterและdevB/master, refs อื่น ๆและrefs/foo/bar refs/foo/bazทุกอย่างเป็นไปตามที่เคยเป็นในรีโมทโคลน การติดตามระยะไกลได้รับการตั้งค่าเพื่อที่ว่าหากคุณเรียกใช้การgit remote updateอ้างอิงทั้งหมดจะถูกเขียนทับจากจุดเริ่มต้นราวกับว่าคุณเพิ่งลบมิเรอร์และปรับเปลี่ยนใหม่ ดังที่เอกสารต้นฉบับกล่าวว่ามันเป็นกระจกเงา มันควรจะเป็นสำเนาที่เหมือนฟังก์ชั่นซึ่งสามารถใช้แทนกันได้กับต้นฉบับ


"Normal clone" อ้างถึง clone ที่ไม่มีธง --bare หรือ - mirror หรือไม่?
แซม

1
ใช่มันเป็นเช่นนั้น ด้วยโคลนเปล่าดังที่ได้กล่าวไว้ในหน้า man สาขาจะถูกคัดลอกโดยตรงเช่นกัน (ไม่มีการอ้างอิง / รีโมท / แหล่งกำเนิดไม่มีการติดตาม) แก้ไขแล้ว
Cascabel

คุณสามารถเพิ่มตัวอย่างการใช้เพิ่มเติมเกี่ยวกับความแตกต่างได้ไหมไม่ใช่แค่ความแตกต่างของ git-internal?
cmcginty

@Casey คือสิ่งที่คุณกำลังมองหา? ฉันไม่คิดว่าสิ่งที่ฉันเขียนไว้เดิมคือ "ภายใน" เลย - แท็กและกิ่งไม้เป็นคุณสมบัติพอร์ซเลนอย่างมาก
Cascabel

"สาขาที่คัดลอกตามที่เป็น" หมายความว่าสาขาถูกคัดลอกไปยังเส้นทางสัมพัทธ์เดียวกันในโคลนหรือไม่ หรือมันแปลว่ากิ่งไม้ถูกแปลงอย่างใด?
Sam

56
$ git clone --mirror $URL

มือสั้นสำหรับ

$ git clone --bare $URL
$ (cd $(basename $URL) && git remote add --mirror=fetch origin $URL)

(คัดลอกโดยตรงจากที่นี่ )

วิธีที่ man-page ปัจจุบันใส่ไว้:

เมื่อเทียบกับ--bare, --mirrorไม่เพียง แต่แผนที่สาขาในประเทศของแหล่งที่สาขาในประเทศเป้าหมายที่จะแผนที่ refs ทั้งหมด (รวมถึงสาขาระยะไกล, บันทึก ฯลฯ ) และตั้งค่าการกำหนดค่า refspec ดังกล่าวว่า refs ทั้งหมดเหล่านี้จะถูกเขียนทับโดยgit remote updateในพื้นที่เก็บข้อมูลเป้าหมาย .


4
ฉันเชื่อว่าคุณต้องทำตามนั้นด้วยgit fetchเพื่อให้เป็นจริง อย่างไรก็ตามนี่เป็นคำตอบที่ไม่ใช่ - ประเด็นของคำถามคือ "กระจกระยะไกล / โคลนแตกต่างจากกระจกธรรมดาอย่างไร"
Cascabel

6
ฉันชอบวิธีนี้แสดงให้เห็นถึงความแตกต่าง หวังว่ามันจะถูกต้อง! ฉันหวังว่า hfs เพิ่มคำสั่งดึงข้อมูล
joeytwiddle

ไม่ชัดเจนจริงๆเช่นการแปลเป็น $ $ (basename $ URL) เป็นอย่างไร
Kzqai

5
basenameเป็นยูทิลิตี้ยูนิกซ์ปกติที่แยกส่วนไดเรกทอรีของเส้นทางและ$()เป็นเพียงการทดแทนคำสั่งทุบตี
Victor Zamanian

6
ยังมี--mirrorอยู่ในนี้ นี้เท่านั้นที่จะเป็นคำตอบที่ได้รับการยอมรับว่ามันอธิบายสิ่งที่git remote add --mirrorไม่
Zenexer

24

การทดสอบของฉันกับ git-2.0.0 วันนี้ระบุว่าตัวเลือก --mirror ไม่ได้คัดลอก hooks ไฟล์กำหนดค่าไฟล์คำอธิบายไฟล์ข้อมูล / ไม่รวมและอย่างน้อยในกรณีทดสอบของฉันสองสาม refs (ซึ่งฉันไม่ได้ ' ไม่เข้าใจ) ฉันจะไม่เรียกมันว่า "สำเนาที่เหมือนกันตามหน้าที่และใช้แทนกันได้กับต้นฉบับ"

-bash-3.2$ git --version
git version 2.0.0
-bash-3.2$ git clone --mirror /git/hooks
Cloning into bare repository 'hooks.git'...
done.

-bash-3.2$ diff --brief -r /git/hooks.git hooks.git
Files /git/hooks.git/config and hooks.git/config differ
Files /git/hooks.git/description and hooks.git/description differ
...
Only in hooks.git/hooks: applypatch-msg.sample
...
Only in /git/hooks.git/hooks: post-receive
...
Files /git/hooks.git/info/exclude and hooks.git/info/exclude differ
...
Files /git/hooks.git/packed-refs and hooks.git/packed-refs differ
Only in /git/hooks.git/refs/heads: fake_branch
Only in /git/hooks.git/refs/heads: master
Only in /git/hooks.git/refs: meta

14

คำอธิบายที่เหมาะสมยิ่งจากเอกสาร GitHub เกี่ยวกับการทำซ้ำ Repository :

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


1
ขอบคุณ; สิ่งนี้ชัดเจนสำหรับฉันว่าแท็กท้องถิ่นจะถูกเขียนทับเช่นเดียวกับสาขาโดยใช้โคลนที่ทำมิเรอร์ มีประโยชน์มาก
Wildcard

2
คุณอาจต้องการใช้--pruneเมื่อเรียกใช้ git fetch เพื่อลบการอ้างอิงแบบโลคัลที่ไม่ได้อยู่บนรีโมตอีกต่อไป
nishanths

13

โคลนคัดลอก refs จากระยะไกลและยัดลงในไดเรกทอรีย่อยชื่อ 'เหล่านี้เป็น refs ที่ระยะไกลมี'

มิเรอร์คัดลอก refs จากรีโมตและวางลงในระดับบนสุดของมัน - มันจะแทนที่ refs ของมันเองกับรีโมต

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


12

ฉันเพิ่มรูปภาพแสดงconfigความแตกต่างระหว่างกระจกกับเปลือย ป้อนคำอธิบายรูปภาพที่นี่ ด้านซ้ายเปลือยด้านขวาเป็นกระจกเงา คุณสามารถล้างไฟล์กำหนดค่าของมิเรอร์มีfetchคีย์ซึ่งหมายความว่าคุณสามารถอัปเดตได้โดยgit remote updateหรือgit fetch --all


3
$ git clone --bare https://github.com/example

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

$ git clone --mirror https://github.com/example

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

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