ในคอมไพล์อะไรคือความแตกต่างระหว่างการผสาน - สควอชและการรีบูต


363

ฉันใหม่กับคอมไพล์และฉันพยายามที่จะเข้าใจความแตกต่างระหว่างสควอชและการรีบูต ตามที่ฉันเข้าใจแล้วว่าคุณเล่นสควอชเมื่อทำการ rebase

คำตอบ:


360

ทั้งสองgit merge --squashและgit rebase --interactiveสามารถผลิตกระทำ "แบน"
แต่พวกเขาตอบสนองวัตถุประสงค์ที่แตกต่าง

จะสร้างการส่งข้อมูลบีบอัดบนสาขาปลายทางโดยไม่ทำเครื่องหมายความสัมพันธ์ผสานใด ๆ
(หมายเหตุ: มันไม่ได้สร้างความมุ่งมั่นทันที: คุณต้องการเพิ่มเติมgit commit -m "squash branch")
สิ่งนี้มีประโยชน์ถ้าคุณต้องการที่จะทิ้งสาขาของแหล่งที่มาอย่างสมบูรณ์ไปจาก (schema นำมาจากคำถาม SO ):

 git checkout stable

      X                   stable
     /                   
a---b---c---d---e---f---g tmp

ถึง:

git merge --squash tmp
git commit -m "squash tmp"

      X-------------------G stable
     /                   
a---b---c---d---e---f---g tmp

แล้วลบtmpสาขา


หมายเหตุ: git mergeมี--commitตัวเลือก--squashแต่ก็ไม่สามารถนำมาใช้กับ มันเป็นไปไม่ได้ที่จะใช้--commitและ--squashรวมกัน
ตั้งแต่ Git 2.22.1 (ไตรมาสที่ 3 ปี 2019) ความไม่ลงรอยกันนี้ทำให้ชัดเจน:

ดูกระทำ 1d14d0c (24 พฤษภาคม 2019) โดยVishal Verma (reloadbrain )
(ผสานโดยJunio ​​C Hamano - gitster-ในการกระทำ 33f2790 , 25 กรกฎาคม 2019)

merge: ปฏิเสธ--commitด้วย--squash

ก่อนหน้านี้เมื่อ--squashมีการให้บริการ ' option_commit' ก็ถูกส่งไปอย่างเงียบ ๆ สิ่งนี้น่าประหลาดใจสำหรับผู้ใช้ที่พยายามจะแทนที่พฤติกรรมที่ไม่ส่งมอบสควอชโดยใช้--commitอย่างชัดเจน

git/git builtin/merge.c#cmd_merge() ตอนนี้รวมถึง:

if (option_commit > 0)
    die(_("You cannot combine --squash with --commit."));

ซ้ำบางส่วนหรือทั้งหมดของคุณมุ่งมั่นในฐานใหม่ช่วยให้คุณสควอช (หรือเมื่อเร็ว ๆ นี้ "แก้ไข" ดูคำถามนี้SO ) ไปที่:

git checkout tmp
git rebase -i stable

      stable
      X-------------------G tmp
     /                     
a---b

หากคุณเลือกที่จะสควอชกระทำทั้งหมดของtmp(แต่ตรงกันข้ามmerge --squashคุณสามารถเลือกที่จะเล่นซ้ำบางส่วนและบีบคนอื่น ๆ )

ดังนั้นความแตกต่างคือ:

  • squashไม่ได้แตะสาขาต้นทางของคุณ ( tmpที่นี่) และสร้างการคอมมิทเดียวที่คุณต้องการ
  • rebaseช่วยให้คุณดำเนินการในสาขาต้นทางเดียวกัน (ยังtmp) ด้วย:
    • ฐานใหม่
    • ประวัติที่สะอาดกว่า

11
Gถูกc--d--e--f--gแบนด้วยกันไหม?
Wayne Conrad

8
@Wayne: ใช่ G ในตัวอย่างเหล่านั้นเป็นตัวแทนของการtmpกระทำที่ถูกแบน
VonC

3
@ Th4wn: เนื่องจากเหตุผล Git กับภาพรวมของโครงการทั้งหมดGจะได้เป็นตัวแทนของเนื้อหาเดียวกันกว่าเพราะการเปลี่ยนแปลงการแนะนำให้รู้จักg X
VonC

1
@VonC: ไม่แน่ใจเกี่ยวกับความคิดเห็นล่าสุด หากคุณมีสิ่งใดสิ่งหนึ่งgit merge --no-ff tempแทนคุณgit merge --squash tempก็จะได้รับประวัติของเมสไซเออร์ แต่คุณสามารถทำสิ่งต่างgit revert eๆ ได้ง่ายขึ้น มันเป็นเรื่องยุ่ง แต่ประวัติศาสตร์ที่ซื่อสัตย์และเป็นประโยชน์และสาขาหลักยังคงสะอาดอยู่พอสมควร
naught101

2
@ naught101 ฉันเห็นด้วย ตามที่อธิบายไว้ในstackoverflow.com/a/7425751/6309แต่มันก็ไม่แตกgit bisectหรือgit blameเมื่อใช้บ่อยเกินไป (เช่นในgit pull --no-ff: stackoverflow.com/questions/12798767/ … ) ยังไม่มีวิธีการหนึ่งซึ่งเป็นเหตุผลที่บทความนี้อธิบายถึงสามวิธี ( stackoverflow.com/questions/9107861/ … )
VonC

183

การรวมกระทำ: รักษาทุกการกระทำในสาขาของคุณและแทรกพวกเขาด้วยการกระทำในสาขาฐานป้อนคำอธิบายรูปภาพที่นี่

ผสานสควอช: เก็บการเปลี่ยนแปลง แต่ละเว้นการกระทำของแต่ละบุคคลจากประวัติศาสตร์ ป้อนคำอธิบายรูปภาพที่นี่

Rebase: สิ่งนี้จะย้ายสาขาฟีเจอร์ทั้งหมดเพื่อเริ่มต้นที่ส่วนปลายของมาสเตอร์มาสเตอร์โดยรวมการคอมมิตใหม่ทั้งหมดในมาสเตอร์

ป้อนคำอธิบายรูปภาพที่นี่

เพิ่มเติมเกี่ยวกับที่นี่


81

ผสานสควอชผสานต้นไม้ (ลำดับของการคอมมิท) เป็นคอมมิทเดียว นั่นคือมันsquashesเปลี่ยนแปลงทั้งหมดที่ทำในnกระทำเป็นหนึ่งกระทำ

การรีบูตเป็นฐานอีกครั้งนั่นคือการเลือกฐานใหม่ (กระทำแม่) สำหรับต้นไม้ บางทีคำศัพท์ทางการค้าสำหรับเรื่องนี้ชัดเจนกว่า: พวกเขาเรียกมันว่าการปลูกถ่ายเพราะมันเป็นเพียงแค่: การเลือกพื้นดินใหม่ (การกระทำของผู้ปกครองราก) สำหรับต้นไม้

เมื่อทำการรีบูตแบบโต้ตอบคุณจะได้รับตัวเลือกให้เลือกสควอชเลือกแก้ไขหรือข้ามการคอมมิทที่คุณจะทำการรีบูต

หวังว่าชัดเจน!


7
ฉันควรรีบูทเมื่อไหร่และควรสควอชเมื่อใด
Martin Thoma

31

เริ่มจากตัวอย่างต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้เรามี 3 ตัวเลือกในการรวมการเปลี่ยนแปลงของฟีเจอร์ย่อยเป็นสาขาหลัก :

  1. การรวมกระทำ
    จะเก็บประวัติการกระทำของสาขาฟีเจอร์ทั้งหมดและย้ายไปไว้ในสาขาหลัก
    จะเพิ่มการกระทำจำลองแบบพิเศษ

  2. Rebase และ merge
    จะผนวกประวัติการคอมมิชชันทั้งหมดของฟีเจอร์ด้านหน้าสาขาหลัก
    จะไม่เพิ่มการกระทำหลอกตา

  3. สควอชและผสาน
    จะจัดกลุ่มสาขาคุณลักษณะทั้งหมดให้เป็นหนึ่งการกระทำจากนั้นผนวกที่ด้านหน้าของสาขาหลัก
    จะเพิ่มการกระทำจำลอง

คุณสามารถดูด้านล่างว่าสาขาหลักจะดูแลสาขาแต่ละสาขาอย่างไร

ป้อนคำอธิบายรูปภาพที่นี่

ในทุกกรณี:
เราได้อย่างปลอดภัยสามารถลบสาขาคุณลักษณะ


1
คุณสามารถอธิบายสิ่งที่จำลองการกระทำในภาพที่ 2 คืออะไร? ฉันเป็นผู้เริ่มต้นในคอมไพล์
ยูซุฟ

1
@ Yusuf เป็นเพียงการกระทำพิเศษซึ่งมีการอัพเดททั้งสองสาขามันเป็นค่าเริ่มต้นส่งข้อความ = "สาขา XYZ สาขา Megre เป็นหลัก"
ahmednabil88
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.