คุณจะใช้กลยุทธ์การรวมคอมไพล์ต่าง ๆ เมื่อใด


429

จากหน้า man บน git-merge มีหลายวิธีในการผสานที่คุณสามารถใช้ได้

  • แก้ไข - วิธีนี้สามารถแก้ไขได้เพียงสองหัวเท่านั้น (เช่นสาขาปัจจุบันและสาขาอื่นที่คุณดึงมา) โดยใช้อัลกอริทึมผสาน 3 ทาง มันพยายามตรวจสอบความคลุมเครือของการผสานไขว้อย่างรอบคอบและถือว่าโดยทั่วไปปลอดภัยและรวดเร็ว

  • recursive - วิธีนี้สามารถแก้ปัญหาสองหัวโดยใช้อัลกอริทึมการผสาน 3 ทาง เมื่อมีบรรพบุรุษร่วมกันมากกว่าหนึ่งคนที่สามารถใช้สำหรับการรวมแบบ 3 ทางมันจะสร้างต้นไม้ที่ผสานของบรรพบุรุษร่วมกันและใช้เป็นต้นไม้อ้างอิงสำหรับการผสานแบบ 3 ทาง สิ่งนี้ได้รับการรายงานว่าส่งผลให้เกิดข้อขัดแย้งในการผสานที่น้อยลงโดยไม่ทำให้เกิดการรวมที่ไม่ถูกต้องโดยการทดสอบในการรวมที่เกิดขึ้นจริงจากประวัติการพัฒนาเคอร์เนล Linux 2.6 นอกจากนี้ยังสามารถตรวจจับและจัดการการรวมที่เกี่ยวข้องกับการเปลี่ยนชื่อ นี่คือกลยุทธ์การผสานเริ่มต้นเมื่อดึงหรือรวมสาขาหนึ่ง

  • octopus - วิธีนี้จะช่วยแก้ไขปัญหามากกว่าสองกรณี แต่ปฏิเสธที่จะรวมที่ซับซ้อนที่ต้องการความละเอียดด้วยตนเอง มันมีความหมายหลักที่จะใช้สำหรับการรวมกลุ่มหัวข้อหัวกัน นี่คือกลยุทธ์การผสานเริ่มต้นเมื่อดึงหรือรวมสาขามากกว่าหนึ่งสาขา

  • ของเรา - สิ่งนี้จะช่วยแก้ไขจำนวนหัวใด ๆ แต่ผลของการผสานจะเป็นหัวสาขาปัจจุบันเสมอ มันมีไว้เพื่อใช้ในการแทนที่ประวัติศาสตร์การพัฒนาแบบเก่า ๆ ของกิ่งก้านสาขา

  • subtree - นี่คือกลยุทธ์แบบเรียกซ้ำที่ปรับเปลี่ยน เมื่อผสานต้นไม้ A และ B ถ้า B สอดคล้องกับต้นไม้ย่อยของ A, B จะถูกปรับก่อนเพื่อให้เข้ากับโครงสร้างต้นไม้ของ A แทนที่จะอ่านต้นไม้ในระดับเดียวกัน การปรับนี้จะกระทำกับต้นไม้บรรพบุรุษร่วมด้วย

ฉันควรระบุสิ่งที่แตกต่างจากค่าเริ่มต้นเมื่อใด สถานการณ์ใดที่ดีที่สุดสำหรับแต่ละสถานการณ์?

คำตอบ:


305

ฉันไม่คุ้นเคยกับการแก้ไข แต่ฉันใช้คนอื่น:

ซ้ำ

การเรียกซ้ำเป็นค่าเริ่มต้นสำหรับการรวมที่ไม่ใช่การกรอไปข้างหน้า เราทุกคนคุ้นเคยกับสิ่งนั้น

ปลาหมึกยักษ์

ฉันเคยใช้ปลาหมึกยักษ์เมื่อฉันมีต้นไม้หลายต้นที่ต้องรวมเข้าด้วยกัน คุณเห็นสิ่งนี้ในโครงการขนาดใหญ่ที่มีสาขาหลายแห่งมีการพัฒนาที่เป็นอิสระและทั้งหมดพร้อมที่จะรวมกันเป็นหัวเดียว

กิ่งปลาหมึกยักษ์ผสานหลายหัวในหนึ่งการกระทำตราบใดที่มันสามารถทำได้อย่างหมดจด

สำหรับภาพประกอบลองนึกภาพว่าคุณมีโครงการที่มีต้นแบบแล้วสามสาขาที่จะรวมเข้าด้วยกัน (เรียกพวกเขาว่า a, b และ c)

ชุดของการรวมแบบเรียกซ้ำจะมีลักษณะเช่นนี้ (โปรดทราบว่าการผสานครั้งแรกเป็นการส่งต่อที่รวดเร็วเนื่องจากฉันไม่ได้บังคับให้เรียกซ้ำ)

ชุดของการรวมซ้ำแบบเรียกซ้ำ

อย่างไรก็ตามการรวมปลาหมึกยักษ์เดียวจะมีลักษณะเช่นนี้:

commit ae632e99ba0ccd0e9e06d09e8647659220d043b9
Merge: f51262e... c9ce629... aa0f25d...

รวมปลาหมึก

ของเราเอง

ของเรา == ฉันต้องการดึงหัวอื่น แต่ทิ้งการเปลี่ยนแปลงทั้งหมดที่หัวแนะนำ

สิ่งนี้จะเก็บประวัติของสาขาโดยไม่มีผลกระทบใด ๆ ของสาขา

(อ่าน: มันไม่ได้ดูที่การเปลี่ยนแปลงระหว่างกิ่งเหล่านั้นกิ่งไม้เพิ่งถูกผสานและไม่มีอะไรทำกับไฟล์ถ้าคุณต้องการผสานในสาขาอื่นและทุกครั้งที่มีคำถาม "รุ่นไฟล์ของเราหรือของพวกเขา รุ่น "คุณสามารถใช้git merge -X ours)

ทรีย่อย

ทรีย่อยมีประโยชน์เมื่อคุณต้องการรวมในโครงการอื่นในไดเรกทอรีย่อยของโครงการปัจจุบันของคุณ มีประโยชน์เมื่อคุณมีห้องสมุดที่คุณไม่ต้องการรวมไว้เป็น submodule


1
ดังนั้นข้อได้เปรียบที่แท้จริงของ Ocotopus เพียงอย่างเดียวคือการลดจำนวนการรวมในต้นไม้
อ็อตโต

60
คุณไม่จำเป็นต้องระบุกลยุทธ์การรวมปลาหมึกยักษ์ : มันถูกใช้โดยอัตโนมัติหากคุณรวมสาขามากกว่าสองสาขา ( git merge A B ...)
Jakub Narębski

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

4
gitgสำหรับผู้ที่อยู่ในสภาพแวดล้อมที่ลินุกซ์
Akash Agrawal

2
คำใบ้-X oursนี้ยอดเยี่ยมเพียงช่วยฉันทำงานหนึ่งชั่วโมง
ไมเคิล

49

จริงๆแล้วสองกลยุทธ์ที่คุณต้องการเลือกคือของเราหากคุณต้องการละทิ้งการเปลี่ยนแปลงที่นำโดยสาขา แต่เก็บสาขาไว้ในประวัติศาสตร์และทรีย่อยถ้าคุณรวมโครงการอิสระเข้ากับไดเรกทอรีย่อยของ superproject (เช่น 'git-gui' ใน ' ที่เก็บ git ')

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


ฉันต้องเลือก 'แก้ไข' แทนค่าเริ่มต้น 'เรียกซ้ำ' สำหรับการผสานสองหัวที่มีข้อผิดพลาด git-tree-tree ที่ร้ายแรง กลยุทธ์ 'แก้ไข' ผสานอย่างหมดจด มันอาจจะเกี่ยวข้องกับการย้ายไฟล์จำนวนมากในสาขาที่ถูกผสาน
thaddeusmt

@thaddeusmt: น่าสนใจ คุณช่วยกรุณาถ้าเป็นไปได้โพสต์รายงานข้อผิดพลาดเกี่ยวกับความล้มเหลวของกลยุทธ์การรวมแบบ "เรียกซ้ำ" ในรายการส่งเมลคอมไพล์ ขอบคุณล่วงหน้า.
Jakub Narębski

@ JakubNarębskiฉันไม่แน่ใจว่าฉันจะรวบรวมข้อมูลที่เพียงพอเพื่อรายงานข้อผิดพลาดที่มีความหมายได้อย่างไรฉันเป็น n00b กับ Git ขอโทษ ดังที่ฉันกล่าวถึงในคำตอบของฉันที่นี่ ( stackoverflow.com/a/10636464/164439 ) การเดาของฉันคือการที่ฉันทำซ้ำการเปลี่ยนแปลงในทั้งสองสาขาและ "การแก้ไข" ทำได้ดีกว่าการข้ามการเปลี่ยนแปลงที่ทำซ้ำ
thaddeusmt

@ JakubNarębskiตอนนี้คุณยังสามารถเลือกพวกเขาซึ่งเป็นไปตามคู่มือ "ตรงข้ามของเรา . สำหรับพวกเขาได้รับการแต่งตั้งค่าโดยอัตโนมัติสำหรับคุณอาจคุณเล็กน้อยสามารถอัปเดตของคุณ Anwser เพิ่ม. พวกเขามีตัวเลือก
SebNag

3
@SebTu: ไม่มีtheirsกลยุทธ์การรวม (นั่นคือ--strategy=theirs) แต่มีtheirsตัวเลือกสำหรับrecursiveกลยุทธ์การผสานเริ่มต้น(นั่นคือ--strategy=recursive --strategy-option=theirsหรือเพียงแค่-Xtheirs)
Jakub Narębski

23

"ผสาน" กับกลยุทธ์การผสาน "แบบเรียกซ้ำ"

การเรียกซ้ำเป็นกลยุทธ์สองหัวเริ่มต้นปัจจุบัน แต่หลังจากการค้นหาบางอย่างในที่สุดฉันก็พบข้อมูลบางอย่างเกี่ยวกับกลยุทธ์การผสาน "แก้ไข"

นำมาจากการควบคุมเวอร์ชันหนังสือของ O'Reilly ด้วย Git ( Amazon ) (ถอดความ):

แต่เดิม "แก้ไข" เป็นกลยุทธ์เริ่มต้นสำหรับการรวม Git

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

ฉันได้ผสานต้นไม้เข้าด้วยกันโดยใช้ "การแก้ไข" ที่ล้มเหลวด้วยกลยุทธ์แบบเรียกซ้ำเริ่มต้น ฉันได้รับfatal: git write-tree failed to write a treeข้อผิดพลาดและต้องขอบคุณโพสต์บล็อกนี้ ( มิเรอร์ ) ฉันลอง "-s resolve" ซึ่งใช้งานได้ ฉันยังไม่แน่ใจว่าทำไม ... แต่ฉันคิดว่ามันเป็นเพราะฉันมีการเปลี่ยนแปลงที่ซ้ำกันในต้นไม้ทั้งสองและแก้ไข "ข้าม" อย่างถูกต้อง


ฉันกำลังใช้การผสาน 3 ทิศทาง (p4merge) และฉันมีข้อขัดแย้งที่เขียนลงในไฟล์. BASE เมื่อการเวียนซ้ำไม่สำเร็จ การถอยกลับเพื่อแก้ไขกลยุทธ์ช่วยในกรณีนี้
mrzl


-2

เนื่องจากคำตอบข้างต้นไม่แสดงรายละเอียดกลยุทธ์ทั้งหมด ยกตัวอย่างเช่นคำตอบบางส่วนจะหายไปรายละเอียดเกี่ยวกับการนำเข้าresolveตัวเลือกและrecursiveซึ่งมีตัวเลือกย่อยเป็นจำนวนมากours, theirs, patience, renormalizeฯลฯ

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

https://git-scm.com/docs/merge-strategies

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