Guideline for merging : แนวทางการ merge branch บน Github
ในการทำงานร่วมกันเป็นทีมบน Project ใน Github นั้น การแตกสาขา(Branch) จากโค้ดหลัก เป็นสิ่งที่ต้องทำ เพื่อที่จะสามารถเพิ่มและแก้ไขโค้ดโดยไม่ให้กระทบกับงานที่คนอื่นทำอยู่ได้ บทความนี้จะเขียนถึงขั้นตอนหลังจากที่เราแก้ไขโค้ดแล้ว ว่าจะนำการเปลี่ยนแปลงที่อยู่ใน Branch แยกของเรา ไป Merge เข้ากับ Branch หลักของ Project อย่างไร ให้ไม่เกิด Conflict กับโค้ดคนอื่นในทีม และสามารถอ่านได้ว่าเราได้ทำการเปลี่ยนแปลงอะไรไปแล้วบ้าง
สิ่งที่ควรทำก่อนการ Merge
ก่อนที่เราจะทำการ merge pull request โค้ดของเราใน branch แยก เข้าไปรวมกับ code หลักที่อยู่ใน Main branch แล้วมีสิ่งที่เราควรต้องทำอยู่ 3 อย่าง นั่นคือ
1. ก่อนที่จะทำการ merge นั้น เราควรทำการอัพเดทโค้ดของเราให้เป็นปัจจุบันให้เท่ากับ Main branch ก่อนเสมอ เพราะการทำงานเป็นทีมบน github นั้น Main branch มักจะมีการ update อยู่ตลอดเวลา ถ้าหากคนในทีมเราไปแก้โค้ดในไฟล์เดียวกับเรา ก่อนที่เราจะสร้าง pull request เพื่อทำการ merge นั้น github จะแจ้งเตือนว่าเกิดการ Conflict ขึ้น ดังภาพ
เพื่อที่จะแก้ไข conflict นั้น สามารถทำได้ 2 ทาง คือ
-
Rebase main branch เข้ามาอยู่ใน branch ของเรา การ rebase จะนำ commit (ชุดการเปลี่ยนแปลงโค้ด) ใน main branch ที่ไม่มีใน branch เรามาเรียงก่อนหน้า commit ที่เราทำการเปลี่ยนแปลง
-
Merge main branch เข้ามาใน branch ของเรา โดยการ merge จะนำ commit ใน main branch มารวมกับ branch ของเราโดยตรง สร้างเป็น commit ใหม่ข้างหน้า commit ของเราที่ยังไม่ merge เข้าไป
โดยระหว่างการ rebase กับ merge จะสามารถแก้ไข conflict ที่เกิดขึ้นได้
- Rebase กับ merge จะต่างกันที่ rebase จะไม่มี commit ใหม่ขึ้นมาเหมือนกับ merge แต่หลักๆแล้ว ทั้ง 2 อย่างสามารถใช้ได้เหมือนกันทั้งคู่ แต่ต้องจำไว้ว่า การ rebase จะทำให้ branch แตกต่างจากเดิม จึงไม่ควรทำ rebase ใน branch ที่ใช้กันหลายคน และถ้าทำ rebase branch ที่เคย push ขึ้น github ไปแล้ว จะต้องทำการ force push เพื่อ ส่ง branch ใหม่ขึ้นไป
2. ใน github project ส่วนใหญ่ผู้ที่ setup project จะมีการตั้ง check actions เอาไว้ ส่วนใหญ่จะเอาไว้ตรวจว่า สไตล์การเขียนโค้ดของเรามีมาตรฐานหรือไม่ หรือโค้ดที่เราแก้ทำให้ automated test ไม่ผ่านรึเปล่า ก่อนที่จะนำโค้ดเข้า main branch หาก มี checks ที่ไม่ผ่าน ต้องเอาโค้ดกลับไปแก้ แล้ว commit ใหม่ จนกว่าจะผ่าน ดังภาพ
3. ควรที่จะให้คนอื่นในทีมช่วยตรวจดูโค้ดที่กำลังจะนำเข้า main branch เสมอ โดยภายใน github pull request เราจะสามารถเลือกคนที่จะมาตรวจโค้ดเราได้ การที่มีคนช่วยดูโค้ดของเรา จะช่วยลดโอกาสเขียนโค้ดผิดลงได้ และช่วยให้คนในทีมรู้ว่า เรากำลังจะเอาโค้ดอะไรเข้า main branch หาก ไม่ใช่โค้ดที่ต้องรีบนำเข้า main branch ควรจะรอให้คนตรวจโค้ด Approve งานของเราก่อนที่จะเริ่ม merge โค้ดเข้า main branch ต่อไป
หลังจากที่ทำทั้ง 3 ข้อนี้เรียบร้อยแล้ว จึงค่อยเริ่มทำการ Merge เข้า main branch ต่อไป
เลือกวิธีการ Merge
หลังจากอัพเดทโค้ดเป็นปัจจุบันที่ผ่าน checks ทั้งหมด และ คนในทีม approveโค้ดของเราแล้ว จะสามารถ merge pull request ของเราเข้า main branch ได้ โดยจะมีวิธีการ merge ให้เลือก 3 อย่าง
-
Create merge commit จะเป็นการเอา commit ทั้งหมดเข้ามาต่อใน main branch และ สร้าง merge commit ขึ้นมา โดย commit ทั้งหมดจะถูกนำเข้า main branch เหมือน branch ที่เราmerge เข้ามา
-
Squash and merge จะเป็นการมัดรวม commit ทั้งหมดที่เราทำใน branch ของเรา มารวมเป็น commit เดียว แล้วนำเอาเข้า main branch โดยที่เราสามารถใส่รายละเอียดว่า commit ที่เราเอาเข้ามีเนื้อหาอะไรบ้าง
-
Rebase and merge จะเป็นการ rebase branch ของเราเข้าไปใน main branch การรวมนี้จะไม่เป็นการสร้าง merge commit ใหม่ แต่จะเหมือนเขียน commit ใหม่ขึ้นมาทั้งหมดใน main
ใน 3 ทางเลือกนี้นั้น ปกติในการทำงานเป็นทีมบน github จะเลือกใช้การ create merge commit กับ squash and merge ไม่นิยมใช้การ rebase and merge เพราะจะทำให้ branch main เปลี่ยนไปตลอดทุกครั้งที่ทำการ merge และทำให้คนอื่นในทีมที่แตก branch จาก branch main เก่าต้องทำการแก้ conflict และ force push ตลอดเวลา
ซึ่งระหว่าง create merge commit กับ squash and merge นั้น ก็มีข้อดีข้อเสียต่างกันออกไป
-
Create merge commit จะนำ commit ย่อยๆที่เราอาจจะต้อง push ขึ้นไปเพื่อแก้ checks error หรือ change request มาเข้า branch main ทั้งหมด คนที่มาดู commit branch main ทีหลังจะดูลำบากว่าเราทำอะไรไปบ้าง ถ้าเราทำ commit ย่อยมากเกินไป
-
Squash and Merge จะมัดรวม commit ย่อยๆทั้งหมดใน branch มารวมเป็น commit เดียว ซึ่งจะลดปัญหาเรื่องการสร้าง commit ย่อยมากเกินไปได้ แต่จะมีข้อเสียกับ project ที่ต้องเลือกเอา commit ย่อยๆเข้า production บ่อยๆ เพราะ squash จะนำcommit ย่อยๆมารวมกันทั้งหมด ทำให้เลือก commit ย่อยได้ยาก
ดังนั้นในการ merge เข้า branch main เราควรที่จะคุยกับคนอื่นในทีมก่อนว่าจะใช้การ merge แบบใด โดยเน้นการใช้ให้เหมาะสมกับ project ที่ทำอยู่ในปัจจุบัน
ข้อมูลอ้างอิง
เว็บไซต์สำหรับอ่านเพิ่มเติมเรื่อง merge และ rebase
ข้อมูลอ้างอิงเรื่องวิธีการ merge pull request