คอมไพล์ผสานหลังจากเชอร์รี่เลือกทำงานอย่างไร


190

ลองจินตนาการว่าเรามีmasterสาขา

จากนั้นเราสร้าง newbranch

git checkout -b newbranch

และสร้างใหม่สองคอมมิตถึงnewbranch: commit1และcommit2

จากนั้นเราเปลี่ยนเป็นต้นแบบและทำ cherry-pick

git checkout master
git cherry-pick hash_of_commit1

เมื่อมองgitkดูเราจะเห็นว่าcommit1และเวอร์ชั่นที่เลือกโดยเชอร์รี่นั้นมีแฮชที่แตกต่างกันดังนั้นในทางเทคนิคแล้วพวกมันต่างกันสองคอมมิชชัน

ในที่สุดเราก็รวมnewbranchเป็นmaster:

git merge newbranch

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

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

คำตอบ:


131

คำตอบสั้น ๆ

ไม่ต้องกังวล Git จะจัดการกับมัน

คำตอบที่ยาว

ซึ่งแตกต่างจาก SVN เช่น1 , Git ไม่เก็บกระทำในรูปแบบเดลต้า แต่ภาพรวมตาม 2,3 ในขณะที่ SVN จะพยายามใช้การคอมมิทแต่ละครั้งแบบผสาน (และล้มเหลวด้วยเหตุผลที่แน่นอนที่คุณอธิบาย) โดยทั่วไป Git สามารถจัดการสถานการณ์นี้ได้

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

แหล่งที่มา

1 Skip-Deltas ในการโค่นล้ม
2 พื้นฐาน Git
3 โมเดลวัตถุ Git


40
ที่จริงแล้วฉันว่าคุณควรกังวลเกี่ยวกับการรวมและ "git จะจัดการกับมัน" ไม่ใช่กฎง่ายๆ
cregox

4
ในความเป็นจริงการรวมสามารถทำให้เนื้อหาที่ซ้ำกันในบางกรณี Git จัดการกับมันบางครั้ง แต่บางครั้งก็ไม่
donquixote

นี่เป็นสิ่งที่ผิดอย่างร้ายแรง มีการจัดเก็บไฟล์ไฟล์ในรูปแบบที่สามารถเข้าถึงได้ทั้งหมด และถ้าฉันจำได้อย่างถูกต้อง SVN ใช้ในการจัดเก็บภาพรวม
he_the_great

2
@he_the_great ไม่ รูปแบบการจัดเก็บเฮี๊ยบเดลต้า SVN ของ (! = ภาพรวม) เป็นเอกสารที่ดีในคู่มือ และผมไม่ได้รับสิ่งที่คุณหมายถึงcondevable ฉันไม่ใช่เจ้าของภาษา แต่ฉันค่อนข้างมั่นใจว่าไม่ใช่คำพูดจริง
helmbert

2
@he_the_great แต่แม้เป็นแพ็คแฮชใด ๆ ที่กำหนดสำหรับไฟล์ผลลัพธ์ในไฟล์เต็ม ใช่มันบีบอัดโดยใช้เดลตา แต่ไม่ใช่เดลต้าสำหรับการเปลี่ยนแปลงในคอมมิชชัน แต่แทนเดลตาระหว่างแฮชสำหรับไฟล์ เท่าที่วัตถุที่เกี่ยวข้องยอมรับมันคือการอ้างอิงต้นไม้ที่อ้างอิงแฮสำหรับไฟล์เต็ม ภายใต้ประทุนข้อมูลจะถูกบีบอัดไม่ส่งผลกระทบต่อวิธีการทำงานของคอมไพล์ Git เก็บไฟล์ที่สมบูรณ์เท่าที่มีการกระทำที่เกี่ยวข้อง SVN จะเก็บ deltas สำหรับการกระทำที่ฉันเข้าใจ
Peter Olson

44

หลังจากการรวมคุณอาจได้รับเชอร์รี่ที่ได้รับมอบหมายในประวัติศาสตร์สองครั้ง

วิธีการป้องกันไม่ให้ฉันอ้างจากบทความที่แนะนำสำหรับสาขาที่มีการซ้ำซ้อน (คัดสรรโดยเชอร์รี่) ให้ใช้ rebase ก่อนทำการผสาน:

คอมไพล์ผสานหลังจากคอมไพล์เชอร์รี่เลือก: หลีกเลี่ยงการกระทำที่ซ้ำกัน

ลองนึกภาพเรามีสาขาหลักและสาขา b:

   o---X   <-- master
    \
     b1---b2---b3---b4   <-- b

ตอนนี้เราต้องการความมุ่งมั่นอย่างเร่งด่วนในระดับ b1 และ b3 ในระดับปริญญาโท แต่ไม่ใช่ส่วนที่เหลือในรูปแบบ b ดังนั้นสิ่งที่เราทำคือเช็คเอาท์สาขาหลักและเลือกเชอร์รี่กระทำ b1 และ b3:

$ git checkout master
$ git cherry-pick "b1's SHA"
$ git cherry-pick "b3's SHA"

ผลลัพธ์จะเป็น:

   o---X---b1'---b3'   <-- master
    \
     b1---b2---b3---b4   <-- b

สมมติว่าเราทำอย่างอื่นกับอาจารย์แล้วเราจะได้:

   o---X---b1'---b3'---Y   <-- master
    \
     b1---b2---b3---b4   <-- b

ถ้าตอนนี้เราจะรวมสาขา b เป็นหลัก:

$ git merge b

เราจะได้รับดังต่อไปนี้:

   o---X---b1'---b3'---Y--- M  <-- master
     \                     /
      b1----b2----b3----b4   <-- b

นั่นหมายถึงการเปลี่ยนแปลงที่เกิดขึ้นโดย b1 และ b3 จะปรากฏขึ้นสองครั้งในประวัติศาสตร์ เพื่อหลีกเลี่ยงการที่เราสามารถรีบูตแทนการรวม:

$ git rebase master b

ซึ่งจะให้:

   o---X---b1'---b3'---Y   <-- master
                        \
                         b2'---b4'   <-- b

สุดท้าย:

$ git checkout master
$ git merge b

ให้เรา:

   o---X---b1'---b3'---Y---b2'---b4'   <-- master, b

แก้ไข โดยความเห็นของเดวิดเลม่อน


1
คำแนะนำที่ดีเกี่ยวกับการลดราคา! มันจะ 'ข้าม' การกระทำทั้งหมดที่เชอร์รี่เลือกกระทำโดยอัตโนมัติ
iTake

2
สุจริตมันฟังดูดีเกินไปที่จะเป็นจริงฉันต้องดูด้วยตาของฉัน ไทม์ไลน์สุดท้ายของคุณควรเป็น---Y---b2'---b4'
David Lemon

ทำงานได้อย่างสมบูรณ์แบบ มีประโยชน์มากถ้าคุณไม่ต้องการให้เชอร์รี่เป็นคนทำสองครั้งในประวัติศาสตร์
user2350644

1
ไม่ควรสังเกตว่าในขณะที่การรีบูตมีความสวยงามอันตรายจากการใช้งานก็คือส้อมหรือกิ่งไม้ที่สร้างขึ้นจาก b เก่าจะไม่ซิงค์กัน กด -f?
JHH

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