"การแตกแขนงฟรี" หมายความว่าอย่างไรใน Git
ฉันได้ยินเรื่องนี้บ่อยมากเมื่อพูดถึง Git เมื่อเปรียบเทียบกับระบบควบคุมเวอร์ชันอื่น
ฉันไม่ได้มีโอกาส (?) ที่จะจัดการกับผู้อื่น ( SVNและอื่น ๆ ) ดังนั้นการแยกสาขา "แพง" ในผู้อื่นเป็นอย่างไร
"การแตกแขนงฟรี" หมายความว่าอย่างไรใน Git
ฉันได้ยินเรื่องนี้บ่อยมากเมื่อพูดถึง Git เมื่อเปรียบเทียบกับระบบควบคุมเวอร์ชันอื่น
ฉันไม่ได้มีโอกาส (?) ที่จะจัดการกับผู้อื่น ( SVNและอื่น ๆ ) ดังนั้นการแยกสาขา "แพง" ในผู้อื่นเป็นอย่างไร
คำตอบ:
การอ้างว่า "การแตกแขนงเป็นอิสระในคอมไพล์" เป็นการทำให้เข้าใจได้ง่ายเพราะไม่ใช่ "ฟรี" ต่อ se มองภายใต้ประทุนการเรียกร้องที่ถูกต้องมากขึ้นจะแตกแขนงที่จะพูดว่าเป็นredonkulouslyราคาถูกแทนเพราะสาขามีพื้นการอ้างอิงถึงการกระทำ ฉันกำหนด "ความเลว" ที่นี่เนื่องจากค่าใช้จ่ายน้อยลง
ลองขุดดูว่าทำไม Git ถึง "ถูก" โดยตรวจสอบว่ามีค่าใช้จ่ายประเภทใด:
ที่เก็บ git .git
ส่วนใหญ่ประกอบด้วยไดเรกทอรีที่มีไฟล์ที่มีข้อมูลเมตาที่ git ใช้ เมื่อใดก็ตามที่คุณสร้างสาขาด้วยคอมไพล์เช่นgit branch {name_of_branch}
มีบางสิ่งเกิดขึ้น:
.git/refs/heads/{name_of_branch}
.git/logs/refs/heads/{name_of_branch}
โดยพื้นฐานแล้วไฟล์ข้อความจะถูกสร้างขึ้นสองไฟล์ หากคุณเปิดการอ้างอิงเป็นไฟล์ข้อความเนื้อหาจะเป็น id-sha ของการกระทำที่สาขาชี้ไปที่ โปรดทราบว่าการแตกสาขาไม่ต้องการให้คุณทำการใด ๆเนื่องจากเป็นวัตถุประเภทอื่น ทั้งสองสาขาและการกระทำนั้นเป็น "พลเมืองชั้นหนึ่ง" ในระบบคอมไพล์และวิธีหนึ่งคือคิดถึงความสัมพันธ์ระหว่างสาขาถึงการกระทำโดยรวมมากกว่าการจัดองค์ประกอบ หากคุณลบสาขาการกระทำจะยังคงมีอยู่ว่า หากคุณนำสาขาออกโดยไม่ได้ตั้งใจคุณสามารถลองหาคำสั่งด้วยgit-lost-found
หรือgit-fsck --lost-found
สร้างสาขาบน sha-id ที่คุณพบว่าค้างอยู่ (และตราบใดที่ git ยังไม่ได้ทำการรวบรวมขยะ)
ดังนั้นคอมไพล์จึงติดตามสาขาที่คุณกำลังทำอยู่ได้อย่างไร? คำตอบนั้นอยู่ที่.git/HEAD
ไฟล์ซึ่งมีลักษณะเช่นนี้หากคุณอยู่ในmaster
สาขา
ref: refs/heads/master
การสลับสาขาเพียงแค่เปลี่ยนการอ้างอิงใน.git/HEAD
ไฟล์จากนั้นดำเนินการเปลี่ยนแปลงเนื้อหาของเวิร์กสเปซของคุณด้วยสิ่งที่กำหนดไว้ในคอมมิท
ในการโค่นล้มสาขาไดเรกทอรีเสมือนในพื้นที่เก็บข้อมูล ดังนั้นวิธีที่ง่ายที่สุดในการแยกสาขาคือทำจากระยะไกลด้วยสายการบินsvn copy {trunk-url} {branch-url} -m "Branched it!"
เดียว SVN จะทำอะไรต่อไปนี้:
trunk
ไปยังไดเรกทอรีเป้าหมายคุณจะต้องดำเนินการนี้จากระยะไกลบนเซิร์ฟเวอร์เนื่องจากการทำสำเนาภายในเครื่องนั้นเป็นการดำเนินการเชิงเส้นเวลาโดยมีไฟล์ที่ถูกคัดลอกและเชื่อมโยง นี่เป็นการดำเนินการที่ช้ามากในขณะที่ทำบนเซิร์ฟเวอร์เป็นการดำเนินการเวลาคงที่ โปรดทราบว่าแม้เมื่อทำการแยกสาขาบนเซิร์ฟเวอร์ย่อยการโค่นล้มต้องใช้การส่งข้อมูลเมื่อทำการแยกในขณะที่ git ไม่ได้ซึ่งเป็นความแตกต่างที่สำคัญ นั่นเป็นค่าใช้จ่ายประเภทหนึ่งที่ทำให้ SVN ราคาถูกน้อยกว่า Git
คำสั่งสำหรับการเปลี่ยนสาขาใน SVNคือsvn switch
เป็นจริงsvn update
ในการปลอมตัว ขอบคุณแนวคิดไดเรกทอรีเสมือนคำสั่งมีความยืดหยุ่นใน svn มากกว่าในคอมไพล์ ไดเร็กทอรีย่อยในเวิร์กสเปซของคุณสามารถเปลี่ยนเป็นมิเรอร์ url ที่เก็บอื่นได้ สิ่งที่ใกล้เคียงที่สุดคือการใช้git-submodule
แต่การใช้ที่ค่อนข้างแตกต่างจากการแยกสาขา น่าเสียดายที่นี่ยังเป็นการตัดสินใจออกแบบที่ทำให้การสลับช้าลงเล็กน้อยใน SVN กว่าใน Git เนื่องจากต้องตรวจสอบทุกไดเรกทอรีพื้นที่ทำงานที่มี URL ระยะไกลเป็นมิเรอร์ จากประสบการณ์ของผม Git นั้นเปลี่ยนเร็วกว่า SVN เร็วกว่า
การแตกแขนงของ SVN นั้นมาพร้อมกับค่าใช้จ่ายเพราะมันจะทำการคัดลอกไฟล์ ในคอมไพล์ตามที่อธิบายไว้ข้างต้นสาขาคือ "เพียงแค่การอ้างอิง" และสามารถเก็บไว้ในพื้นที่เก็บข้อมูลในท้องถิ่นของคุณและถูกเผยแพร่ตามดุลยพินิจของคุณ จากประสบการณ์ของฉันอย่างไรก็ตาม SVN ยังมีราคาถูกกว่าและมีประสิทธิภาพมากกว่าเช่น ClearCase
เป็นเพียงคนเกียจคร้านที่ SVN ไม่ได้กระจายอำนาจ คุณสามารถมีที่เก็บหลายแห่งเป็นมิเรอร์ไปยัง repo บางแหล่ง แต่การซิงค์การเปลี่ยนแปลงที่แตกต่างกันหลายที่เก็บ SVN นั้นเป็นไปไม่ได้เนื่องจาก SVN ไม่มีตัวระบุที่ไม่ซ้ำสำหรับ commits (git มีตัวระบุแฮชที่อิงเนื้อหาของ เหตุผลที่ว่าทำไมผมเองเริ่มใช้คอมไพล์มากกว่า SVN แต่เป็นเพราะการเริ่มต้นการเก็บข้อมูลเป็นอย่างน่าทึ่งง่ายและราคาถูกในการคอมไพล์ แนวคิดในแง่ของการจัดการการกำหนดค่าซอฟต์แวร์สำเนาที่ต่างกันของโครงการ (โคลน, ส้อม, เวิร์กสเปซหรืออะไรก็ตาม) คือ "สาขา" และคำศัพท์นี้ทำให้การสร้างสำเนาใหม่ใน SVN นั้นไม่ถูกเท่า Git สาขา "ในตัว"
เป็นอีกตัวอย่างหนึ่งในMercurial การแตกแขนงเริ่มแตกต่างกันเล็กน้อยในรูปแบบ DVCS และการสร้าง / ทำลายกิ่งที่มีชื่อจะต้องแยกออกจากกัน ผู้พัฒนา Mercurial นำไปใช้ในภายหลังในการพัฒนาบุ๊กมาร์กเพื่อเลียนแบบรูปแบบการแยกสาขาของ git แม้ว่าheads
จะถูกเรียกtips
และbranches
อยู่bookmarks
ในคำศัพท์ของ mercurial แทน
This command causes a near-instantaneous commit in the repository, creating a new directory in revision 341. The new directory is a copy of /calc/trunk.
- การสร้างสาขานั้นเป็นเรื่องเล็กน้อยใน SVN เว้นแต่คุณจะทำสำเนาทุกไฟล์อย่างชัดเจน
ต้นทุนที่แท้จริงของสาขากำลังรวมเข้าด้วยกัน Git ทำให้ง่ายกว่าระบบควบคุมแหล่งอื่น ดูคำถาม Stack Overflow อย่างไรและ / หรือทำไมการผสานใน Git ดีกว่าใน SVN .
ใน Git สาขาจะมีการอ้างอิงถึงคอมมิชชันต่อ repo ท้องถิ่น สร้างมันราคาถูกมากไม่มีเครือข่ายเลย ไม่ฟรี (คุณต้องพิมพ์คำสั่ง) แต่ให้ตายเถอะ
การแตกแขนงไม่ได้แพงมากใน SVN แต่เป็นเพียงแค่สำเนาซึ่งเป็นการกระทำที่ราคาถูกมาก SVN มีโมเดลพื้นที่เก็บข้อมูลส่วนกลางดังนั้นจึงเป็นการเข้าถึงเครือข่าย แต่ไม่ใช่รุ่นที่น่ากลัว
ในทางกลับกัน CVS ในทางกลับกันการแตกแขนงนั้นมีราคาแพงมาก โดยทั่วไปแล้วสาขา CVS เกี่ยวข้องกับการเพิ่มแท็ก แต่ใน CVS ซึ่งหมายความว่าทุกไฟล์ที่ได้รับผลกระทบจะต้องมีการแก้ไข แต่ละไฟล์ถูกเขียนใหม่เพื่อรวมแท็กใหม่ มันมีราคาแพงมาก และถ้าที่เก็บของคุณใหญ่มันก็ช้าเหมือนกัน อันที่จริงถ้าคุณอยู่ในโครงการขนาดใหญ่มันช้าพอที่คนบางคนมักจะหลีกเลี่ยงการสร้างสาขาหากพวกเขาทำได้
การแยกสาขาของ SVN นั้นฟรีเท่ากับของ Git มันเป็นเพียงข้อมูลการดูแลเล็กน้อยที่บอกว่าสาขาเริ่มต้นจากที่ไหนไม่มีการเปลี่ยนแปลงไฟล์ที่เก็บไว้ แต่อย่างใด 'คัดลอก' ใน SVN เหมือนกับการเพิ่ม symlink ไปยังไดเรกทอรี Unix โปรดทราบว่าสาขา SVN จะไม่ต้องใช้การเดินทางผ่านเครือข่ายจนกว่าคุณจะยอมรับการเปลี่ยนแปลงสำเนาการทำงานของคุณ (แต่มีจุด SCM ไม่มากนักหากคุณไม่ได้กระทำการนอกพื้นที่ในบางจุด)
โปรดทราบว่าสาขา Git จะเกี่ยวข้องกับการดูแลรักษาบางอย่างเช่นการเพิ่มแท็กนั้นไว้ภายในซึ่งจะต้องถูกเก็บไว้ที่ใดที่หนึ่งเมื่อคุณส่งมอบ มันไม่ใช่เรื่องใหญ่เลยซึ่งเป็นเหตุผลว่าทำไมมันถึงเรียกว่า 'ฟรี'
มันเป็น 'ฟรี' (ในบริบทนี้ 'ฟรี' จริงๆหมายถึงความรวดเร็วและไม่ต้องเสียพื้นที่) เพราะในระบบควบคุมเวอร์ชันเก่าบางสาขาสาขาก็เป็นสำเนาที่สมบูรณ์ของรหัส ณ จุดนั้นดังนั้นสาขาจึงใช้เวลามาก พื้นที่และเป็นเรื่องง่ายที่จะจบลงด้วยซอฟต์แวร์เวอร์ชั่นเต็มรูปแบบที่แตกต่างกันจำนวนมากที่วางอยู่รอบ ๆ ในที่อื่น ๆ มันไม่ได้เป็นสำเนาที่สมบูรณ์ของรหัส แต่ทุกไฟล์ยังคงต้องมีการแก้ไขสำหรับแท็กดังนั้นจึงช้าและเจ็บปวด ('แพง')
อีกแง่มุมหนึ่งของ "ฟรี / ราคาถูก / แพง" ก็คือต้นทุนของนักพัฒนาในการจัดการกับผลที่ตามมาจากการแตกสาขา; เช่นกระบวนการของการรวมการเปลี่ยนแปลงจากสาขา
และที่นี่การรวมสาขาในระบบ DVCS เช่น Git และ Mercurial นั้นง่ายกว่าในระบบเก่า ... เพราะระบบ DVCS นั้นทำงานได้ดีกว่ามากในการติดตามประวัติของเวอร์ชันในกราฟ เช่นที่การแตกแขนงก่อนหน้านี้มีการรวมกันเกิดขึ้น สิ่งนี้ทำให้การผสานมีความแม่นยำยิ่งขึ้นลดความขัดแย้งที่ไม่จำเป็นและ ... ทำให้การผสาน "ง่ายขึ้น" หรือ "น่ากลัวน้อยลง" สำหรับผู้พัฒนาที่เกี่ยวข้อง