Merge คืออะไร
2 วิธีที่ Git รวม branch กลับมาเป็นหนึ่ง: fast-forward (เลื่อน label) และ 3-way merge (สร้าง commit พิเศษมี 2 parent)
ใน lesson ที่แล้วคุณเห็น branch แยกสายทำงานได้ ไม่ชนกัน แต่สุดท้ายเมื่อ feature ทำเสร็จ เราก็อยากเอามันกลับมารวมเข้า main เพื่อเป็นของจริงที่ทุกคนใช้ นี่คือการทำ merge
Merge = รวม 2 branch เป็นหนึ่ง
การ merge คือการบอก Git ว่า “เอา commit ของ branch นี้มารวมกับ branch ที่ฉันอยู่ตอนนี้” แต่รูปแบบการรวมมี 2 แบบ ขึ้นอยู่กับสถานการณ์ ลองมาดูทั้งสองแบบทีละอัน
แบบแรก: Fast-forward merge
ถ้าตั้งแต่แยก branch ออกไป main ไม่ได้มี commit ใหม่เพิ่มเลย (ยังอยู่ที่เดิม) ส่วน feature เดินหน้าต่อเพิ่มไป 2 commit การ merge feature เข้า main ก็แค่ เลื่อน label main ไปที่ commit ล่าสุดของ feature ไม่ต้องสร้าง commit ใหม่เลย
5f2a8c9 feature ล้ำไปข้างหน้า 2 commitเมื่อ main ไม่ได้มี commit ใหม่หลังแยก branch merge ก็แค่ “เลื่อน label” main ไปที่ commit ล่าสุดของ feature Git เรียกว่า fast-forward merge
แบบที่สอง: 3-way merge (merge commit)
ถ้าทั้ง main และ feature ต่างก็มี commit ใหม่หลังแยก branch Git ไม่สามารถ fast-forward ได้ เพราะประวัติ “แยกเส้น” ไปคนละทางแล้ว ทางเดียวที่จะรวมสองเส้นกลับมาได้คือสร้างmerge commit พิเศษที่มี parent 2 ตัว
เมื่อทั้ง 2 branch มี commit ใหม่หลังแยก Git ทำแบบ fast-forward ไม่ได้ เพราะ main ไม่ได้อยู่ก่อน feature ต้องสร้าง merge commit ที่มี parent 2 ตัว (main tip และ feature tip) รวมเนื้อหาจากทั้งสองฝั่งเข้าด้วยกัน
สังเกตว่า commit ใหม่ที่เกิดจาก merge มีลูกศรชี้ไปหา 2 commit (main tip และ feature tip)
Tip คือศัพท์ที่แปลว่า “commit ล่าสุด (ปลายสุด)” ของ branch นั้น Git ใช้ “3-way” ในชื่อเพราะมันเทียบ 3 จุด:
- Base = commit ร่วมตอนแยก branch (ของเดิม)
- main tip = commit ล่าสุดของ main ตอนนี้
- feature tip = commit ล่าสุดของ feature ตอนนี้
Git เอา diff (ส่วนที่ต่างของไฟล์) ของ main จาก base เทียบกับ diff ของ feature จาก base แล้วรวมเข้าด้วยกันเป็น snapshot ใหม่ของ merge commit
ใช้แบบไหนดี
โดย default Git จะเลือกให้เอง ถ้า fast-forward ได้ก็ใช้ fast-forward ถ้าไม่ได้ก็สร้าง merge commit แต่ทีมจริงๆ มักกำหนด policy เอง เช่น “PR ทุกอันต้อง merge commit เพื่อให้เห็นว่าเคยเป็น branch” หรือ “rebase ก่อน merge เพื่อให้ประวัติเป็นเส้นตรง”
สรุป
- Merge = รวม commit จาก branch หนึ่งเข้ากับ branch ที่เราอยู่
- Fast-forward merge เกิดเมื่อ target branch ไม่ได้เคลื่อน เลื่อน label อย่างเดียว ไม่มี commit ใหม่
- 3-way merge เกิดเมื่อทั้ง 2 branch มี commit ใหม่ ต้องสร้าง merge commit ที่มี 2 parent
- merge commit เชื่อมประวัติทั้งสายกลับเป็นจุดรวม ทำให้ย้อนกลับไปดูได้ครบ