LEVEL 2 · ระดับกลาง
Merge vs Rebase
สองคำสั่งนี้ตอบโจทย์เดียวกัน — "เอางานสองสายมารวมกัน" — แต่ให้ประวัติคนละหน้าตา การเลือกใช้สะท้อนปรัชญาว่าคุณอยากให้ประวัติ บอกความจริงตามที่เกิด หรือ เล่าเรื่องให้อ่านง่าย
8.1 เลือกอย่างไร
| Merge | Rebase | |
|---|---|---|
| ประวัติ | ตามจริง เห็นการแตกสาย | เส้นตรง อ่านเป็นเรื่องเดียว |
| commit เดิม | คงไว้ทั้งหมด | สร้างใหม่ (รหัสเปลี่ยน) |
| เหมาะกับ | รวมงานเข้า branch หลักที่แชร์กัน | เก็บกวาด branch ส่วนตัวให้สะอาดก่อนเสนอ |
ทางเลือกนี้มักผูกกับกลยุทธ์ branch ของทั้งทีมด้วย — trunk-based (บทที่ 10.3) มักไปกับ rebase เพราะอยากได้ประวัติ main เป็นเส้นตรง ส่วน Git Flow ที่มี branch ยืนยาวมักไปกับ merge เพื่อเก็บร่องรอยการแตกสายไว้
8.2 interactive rebase — เครื่องมือเก็บกวาดประวัติ
git rebase -i ให้คุณแก้ชุด commit ก่อนเสนอเข้าทีม — รวมหลาย commit ย่อย ("แก้ typo", "แก้ typo อีกที") ให้เหลือก้อนเดียวที่มีความหมาย, เปลี่ยนข้อความ, สลับลำดับ คำสั่งที่ใช้บ่อย: squash (ยุบรวม), reword (แก้ข้อความ), fixup (ยุบโดยทิ้งข้อความ), drop (ลบ commit)
8.3 conflict ตอน rebase ต่างจาก merge conflict อย่างไร
merge conflict (บทที่ 10.2) เกิดครั้งเดียว แก้จบในคราวเดียว แต่ rebase เล่นซ้ำ (replay) commit ทีละดวงไปวางบนฐานใหม่ ถ้าหลาย commit ต่างชนกับฐานคนละจุด conflict จะโผล่ทีละรอบตามลำดับ ไม่ใช่ครั้งเดียวจบ:
$ git rebase main
CONFLICT (content): Merge conflict in price.js
# แก้ไฟล์ ลบเครื่องหมาย <<< === >>> เหมือน merge conflict ทุกประการ
$ git add price.js
$ git rebase --continue # ไปต่อ commit ถัดไป — อาจเจอ conflict ซ้ำอีกดวงทางเลือกเมื่อติด conflict ระหว่าง rebase: --continue แก้เสร็จแล้วไปต่อ, --skip ข้าม commit นี้ทั้งดวง (ทิ้งการเปลี่ยนแปลงของมันไปเลย), --abort ยกเลิกทั้งหมดกลับไปจุดก่อน rebase เหมือนไม่เคยเริ่ม — ตัวเลือกที่ปลอดภัยที่สุดเวลาพันกันจนไม่แน่ใจ หาก conflict เดิมโผล่ซ้ำหลายรอบระหว่าง rebase ยาว ๆ นั่นคือสถานการณ์ที่ rerere (บทที่ 13) ถูกออกแบบมาแก้โดยเฉพาะ
✅ สรุปบทที่ 8 — merge เก็บประวัติตามจริง (มี merge commit), rebase ทำประวัติให้เป็นเส้นตรงโดยสร้าง commit ใหม่ · ใช้ rebase เก็บกวาด branch ส่วนตัว, ใช้ merge รวมเข้า branch หลัก ·
rebase -iยุบ/แก้/จัดเรียง commit ก่อนเสนอ · conflict ตอน rebase แก้ไฟล์เหมือน merge แต่เกิดซ้ำได้ทีละ commit ใช้--continue/--skip/--abort· กฎเหล็ก: ห้าม rebase สิ่งที่แชร์ไปแล้ว