Notes & software courses · Free to learn
Aph's Blog
On this page

Merge Conflict & Rebase

👋 อ่านฟรีทั้งหมดบน Aph's Blog — เนื้อหาภาษาไทย ทำตามทีละหน้าใน sidebar ได้เลย หากมีข้อเสนอแนะหรืออยากให้เพิ่มหัวข้อไหน บอกได้เสมอ

แก้เมื่อสองคนแก้บรรทัดเดียวกัน และเข้าใจว่า rebase ต่างจาก merge อย่างไร

เมื่อทำงานเป็นทีม จะมีบางครั้งที่สองคนแก้ไฟล์เดียวกันบรรทัดเดียวกัน git รวมเองไม่ได้ เกิด merge conflict — มันไม่น่ากลัว แค่ต้องบอก git ว่าจะเอาเวอร์ชันไหน หัวข้อนี้สอนวิธีแก้และความต่างของ rebase

conflict เกิดและหน้าตาเป็นอย่างไร

เมื่อ merge แล้วชนกัน git จะใส่เครื่องหมายในไฟล์บอกว่าส่วนไหนชน: ของเรา (HEAD) กับของอีกฝั่ง

<<<<<<< HEAD
price = 100        # โค้ดฝั่งเรา (branch ปัจจุบัน)
=======
price = 120        # โค้ดฝั่งที่กำลัง merge เข้ามา
>>>>>>> feature-x

วิธีแก้ conflict

  1. เปิดไฟล์ที่ conflict (git status บอกว่าไฟล์ไหน)
  2. เลือกว่าจะเอาเวอร์ชันไหน หรือรวมมือ แล้วลบเครื่องหมาย <<<<, ====, >>>> ออก
  3. git add ไฟล์ที่แก้แล้ว
  4. git commit เพื่อจบการ merge
bash
git merge feature-x
# CONFLICT (content): Merge conflict in app.py
# ...แก้ไฟล์ให้เหลือเวอร์ชันที่ต้องการ ลบ marker...
git add app.py
git commit              # จบ merge

merge vs rebase

ทั้งคู่รวมงานจากอีก branch แต่ผลต่างกัน: merge สร้าง merge commit รวมสองสาย ส่วน rebase ย้าย commit ของเราไปต่อท้ายอีก branch ทำให้ประวัติเป็นเส้นตรงสวยงาม

mergerebase
ประวัติแตกสาย + merge commitเส้นตรง สะอาด
commit เดิมคงไว้ถูกเขียนใหม่ (hash เปลี่ยน)
เหมาะกับรวมงานเข้า mainเก็บ branch ส่วนตัวให้สะอาดก่อน merge
bash
git switch feature-x
git rebase main         # ย้าย commit ของ feature ไปต่อท้าย main ล่าสุด
กฎทองของ rebase

อย่า rebase branch ที่ push ขึ้น remote แล้วหรือที่คนอื่นใช้อยู่ เพราะ rebase เขียนประวัติใหม่ (hash เปลี่ยน) จะทำให้ของคนอื่นพัง — ใช้ rebase กับ branch ส่วนตัวที่ยังไม่ได้แชร์เท่านั้น

สรุปหัวข้อนี้

  • conflict เกิดเมื่อแก้บรรทัดเดียวกันคนละทาง — git ใส่ marker <<< === >>>
  • แก้: เลือกเวอร์ชัน ลบ marker → git add → git commit
  • merge เก็บประวัติแตกสาย; rebase ทำประวัติเป็นเส้นตรง (เขียน commit ใหม่)
  • ห้าม rebase ของที่ push/แชร์แล้ว
แบบฝึกหัด

1) สร้าง conflict โดยแก้บรรทัดเดียวกันใน 2 branch แล้ว merge 2) แก้ conflict ให้จบ (เลือกเวอร์ชัน, add, commit) 3) ลอง rebase branch ส่วนตัวเข้า main 4) อธิบายว่าทำไมห้าม rebase ของที่แชร์แล้ว