จากความเข้าใจของฉัน SVN คือ 'ง่ายต่อการแตกสาขา ยากที่จะรวม ' ทำไมถึงเป็นอย่างนั้น? มีวิธีแตกต่างกันอย่างไร?
จากความเข้าใจของฉัน SVN คือ 'ง่ายต่อการแตกสาขา ยากที่จะรวม ' ทำไมถึงเป็นอย่างนั้น? มีวิธีแตกต่างกันอย่างไร?
คำตอบ:
โปรดดูคำตอบสแต็คล้นของฉันสำหรับสถานการณ์ที่เป็นรูปธรรมมากที่ Mercurial (และ Git) ผสานเข้าด้วยกันโดยไม่มีปัญหาและที่ Subversion นำเสนอคุณด้วยความขัดแย้งปลอม สถานการณ์เป็นการปรับโครงสร้างอย่างง่ายที่กระทำบนสาขาที่คุณเปลี่ยนชื่อไฟล์บางไฟล์
เมื่อพิจารณาถึงคำตอบของ tdammers แล้วมีจำนวนของความเข้าใจผิดที่นั่น:
การโค่นล้ม Mercurial และ Git สแน็ปช็อตกว้างของที่เก็บแทร็กทั้งหมดของโครงการ เรียกพวกเขารุ่น , การแก้ไขหรือการแก้ไขทำให้ไม่แตกต่าง พวกมันเป็นภาพรวมเชิงอะตอมของชุดของไฟล์
ขนาดของการผูกมัดของคุณไม่ได้ต่างไปจากการรวมเข้าด้วยกัน ทั้งสามระบบผสานกับอัลกอริธึมการผสานสามทางมาตรฐานและอินพุตของอัลกอริทึมนั้น
มันไม่สำคัญว่าทั้งสองรุ่นสาขาที่ถูกสร้างขึ้น คุณสามารถใช้การคอมมิตขนาดเล็กได้ 1,000 ครั้งตั้งแต่เวอร์ชันบรรพบุรุษหรือคุณสามารถใช้การคอมมิท 1 ครั้งได้ สิ่งที่สำคัญคือไฟล์เวอร์ชันสุดท้าย (ใช่นี่เป็นเรื่องที่น่าประหลาดใจใช่แล้วคู่มือ DVCS จำนวนมากจะทำสิ่งนี้ผิดไปอย่างน่ากลัว)
เขายังยกประเด็นที่ดีเกี่ยวกับความแตกต่าง:
การโค่นล้มมีบางส่วน "ของขึ้น" ที่คุณสามารถผสานจากลงในการพูด/trunk
/branches/foo
Mercurial และ Git ไม่ได้ใช้โมเดลนี้ - กิ่งก้านเป็นแบบจำลองโดยตรงในประวัติศาสตร์ ประวัติจึงกลายเป็นกราฟชีทกำกับแทนที่จะเป็นเส้นตรง นี่เป็นรุ่นที่ง่ายกว่ารุ่นที่ใช้โดยการโค่นล้มและจะตัดมุมกรณีจำนวนหนึ่งออกไป
คุณสามารถชะลอการรวมหรือปล่อยให้คนอื่นจัดการได้อย่างง่ายดาย หากhg merge
คุณมีข้อขัดแย้งมากมายคุณสามารถขอให้เพื่อนร่วมงานของคุณhg pull
จากคุณและเขาก็มีสถานะเดียวกัน ดังนั้นเขาสามารถhg merge
และบางทีเขาอาจจะดีกว่าในการแก้ไขความขัดแย้งมากกว่าที่คุณเป็น
นี่เป็นเรื่องยากมากกับการโค่นล้มที่คุณต้องอัปเดตก่อนที่จะส่งมอบ คุณไม่สามารถเพิกเฉยต่อการเปลี่ยนแปลงบนเซิร์ฟเวอร์และกระทำการกับสาขาที่ไม่ระบุชื่อของคุณเอง โดยทั่วไปกองกำลังโค่นล้มคุณที่จะเล่นรอบกับสำเนาการทำงานสกปรกsvn update
เมื่อคุณ สิ่งนี้มีความเสี่ยงเนื่องจากคุณไม่ได้จัดเก็บการเปลี่ยนแปลงของคุณไว้อย่างปลอดภัย Git และ Mercurial ให้คุณยอมรับก่อนจากนั้นอัปเดตและผสานตามความจำเป็น
เหตุผลที่แท้จริง Git และ Mercurial นั้นดีกว่าการควบรวมมากกว่าการโค่นล้มเป็นเรื่องของการดำเนินการ มีการเปลี่ยนชื่อความขัดแย้งที่การโค่นล้มไม่สามารถจัดการได้แม้จะคิดว่ามันชัดเจนว่าคำตอบที่ถูกต้องคืออะไร Mercurial และ Git จัดการสิ่งเหล่านั้นได้อย่างง่ายดาย แต่ไม่มีเหตุผลว่าทำไมการโค่นล้มไม่สามารถจัดการกับสิ่งเหล่านั้นได้ดี - การรวมศูนย์ไม่ใช่เหตุผลอย่างแน่นอน
trunk
ใน SVN ด้วย DVCS คุณสามารถกระทำได้โดยไม่ต้องแชร์ แต่ใน SVN คุณsvn commit
จะส่งผลโดยตรงต่อผู้อื่นที่ทำงานในสาขาเดียวกัน แม้ว่าเราสองคนทำงานในสาขาใน SVN ฉันไม่สามารถทำงานของฉันได้โดยไม่ต้องรวมงานของคุณเข้าด้วยกันทันที นั่นทำให้คอมมิทค่อนข้างน่ากลัว - ซึ่งเป็นคุณสมบัติที่น่ากลัวสำหรับระบบควบคุมเวอร์ชัน! :-)
ปัญหาหลักอยู่ที่วิธีที่ระบบเหล่านี้แสดงถึงโครงสร้างไดเรกทอรีที่มีเวอร์ชัน
แนวคิดพื้นฐานของการโค่นล้มซึ่งระบบทั้งหมดหมุนรอบตัวเป็นของเวอร์ชัน (หรือใน svn lingo, "revision"): สแน็ปช็อตของไฟล์ ณ จุดหนึ่ง ตราบใดที่ประวัติศาสตร์เป็นเส้นตรงอย่างสมบูรณ์ทุกอย่างก็ดี แต่ถ้าคุณต้องการรวมการเปลี่ยนแปลงจากสองสายการพัฒนาอิสระ svn ต้องเปรียบเทียบเวอร์ชันปัจจุบันของทั้งคู่แล้วทำการเปรียบเทียบสามทางระหว่างเวอร์ชันที่แชร์ล่าสุด และสองรุ่นใหญ่ บรรทัดที่ปรากฏในหัวหนึ่ง แต่ไม่สามารถแก้ไขได้อย่างง่ายดาย เส้นที่เบี่ยงเบนไปในทางเดียวกันทั้งสองหัวนั้นยากกว่า แต่มักเป็นไปได้ บรรทัดที่เบี่ยงเบนในรูปแบบที่แตกต่างกันคือสิ่งที่ทำให้ svn พูดว่า "ฉันไม่สามารถเข้าใจสิ่งนี้ได้มนุษย์โปรดแก้ไขสิ่งนี้ให้ฉันด้วย"
ในทางตรงกันข้ามคอมไพล์และติดตามปรอทการแก้ไขมากกว่ารุ่น ที่เก็บทั้งหมดเป็นแผนผังของเซ็ตการแก้ไขแต่ละอันขึ้นอยู่กับพาเรนต์ซึ่งเซ็ตการแก้ไขพาเรนต์สามารถมีลูกได้จำนวนเท่าใดก็ได้และรากของต้นไม้แสดงถึงไดเร็กทอรีว่าง กล่าวอีกนัยหนึ่ง git / hg กล่าวว่า "ก่อนอื่นฉันไม่มีอะไรเลยโปรแกรมแก้ไขนี้จะถูกนำไปใช้งานจากนั้นก็เป็นโปรแกรมแก้ไขดังกล่าว ฯลฯ " เมื่อคุณต้องการผสานการพัฒนาสองบรรทัด git / hg ไม่เพียง แต่รู้ว่าหัวแต่ละคนในปัจจุบันมีลักษณะอย่างไรและดูเหมือนรุ่นทั่วไปที่ผ่านมาอย่างไรมันก็รู้ว่าการเปลี่ยนแปลงเกิดขึ้นได้อย่างไร
อีกสิ่งหนึ่งที่ทำให้การรวมกันง่ายขึ้นใน DVCS คือผลลัพธ์ทางอ้อมของการแยกแนวคิดของการกระทำและการผลักดันและอนุญาตให้มีการรวมข้ามทุกประเภทระหว่างสองโคลนของที่เก็บเดียวกันได้ตลอดเวลา ด้วย svn ผู้คนมักจะทำการเซ็ตอัพเซ็ตขนาดใหญ่ที่มีการเปลี่ยนแปลงที่ไม่เกี่ยวข้องบ่อยครั้งเนื่องจากคอมมิชชันยังเป็นการอัพเดตบนที่เก็บส่วนกลางซึ่งมีผลต่อสมาชิกในทีมอื่น ๆ ทั้งหมด; หากคุณส่งเวอร์ชั่นที่แตกสลายทุกคนจะโกรธคุณ เนื่องจากการตั้งค่าส่วนใหญ่เกี่ยวข้องกับเซิร์ฟเวอร์ svn เครือข่ายการส่งข้อมูลจึงเกี่ยวข้องกับการปั๊มข้อมูลผ่านเครือข่ายซึ่งหมายความว่าการส่งข้อมูลจะทำให้เกิดความล่าช้าในเวิร์กโฟลว์ (โดยเฉพาะเมื่อสำเนาการทำงานของคุณล้าสมัยและคุณต้องดึงก่อน) ด้วยคอมไพล์และเมอร์คิวเรียนคอมมิชชันเกิดขึ้นแบบโลคอลและเนื่องจากทั้งคู่มีประสิทธิภาพมากในการจัดการระบบไฟล์ในท้องถิ่นจึงมักจะเสร็จสิ้นในทันที เป็นผลให้ผู้คน (เมื่อพวกเขาคุ้นเคยกับมัน) จะทำการเปลี่ยนแปลงที่เพิ่มขึ้นเล็กน้อยจากนั้นเมื่อมันทำงาน ผลักดันโหลหรือมากกว่านั้นมุ่งมั่นในครั้งเดียว จากนั้นเมื่อรวมเวลาเข้ามา SCM จะมีข้อมูลที่ละเอียดมากยิ่งขึ้นไปอีกและสามารถแก้ไขข้อขัดแย้งของงานได้อย่างปลอดภัยและอัตโนมัติ
แล้วมีรายละเอียดที่ดีที่ทำให้สิ่งต่าง ๆ ง่ายขึ้น:
hg mv
หรือhg addremove --similarity...
) ในขณะที่ Git ใช้แก้ปัญหา แต่ทั้งสองจับเปลี่ยนชื่อ ฉันสามารถรับความขัดแย้งของต้นไม้ได้แม้จะมีความแตกต่างของสตริง 1ไฟล์ในการรวมกัน! คุณต้องเรียนรู้แง่มุมการโค่นล้มอีกครั้ง
rename a b
ฐานะcopy a b; remove a
และทั้งสองจะทำมันในหนึ่งอะตอมกระทำ พฤติกรรมการผสานที่แตกต่างกันนั้นเกิดจากการใช้งานมุมและการโค่นล้มที่แตกต่างกันทำให้เกิดการรวมกันมากกว่า Mercurial และ Git ในที่สุด Git ตรวจจับการเปลี่ยนชื่อที่รวมและเวลาเข้าสู่ระบบ - เรากำลังคิดที่จะเพิ่มสิ่งนี้ใน Mercurial ด้วย