git rebase vs git merge
ทั้ง git rebase และ git merge ต่างก็เป็นคำสั่งที่เราใช้ในการรวม Code ซึ่งการนำ Code ที่แตกต่างกัน 2 ฃุดมารวมกันเราจะเลือกได้ 2 วิธีคือ ดังรูป
-
git rebase คือการนำ Commit แต่ละตัวมาใส่ใน branch ปัจจุบัน(Move) ซึ่งการ Rebase จะไม่มี Commit ใหม่
-
git merge คือการนำ Code ที่แตกต่างกัน 2 ชุดมารวมกัน(Combine) ดังนั้นการใช้
git merge
จะทำให้เกิด Commit ใหม่
เราควรเลือก Merge และ Rebase อย่างใดอย่างหนึ่งเท่านั้น ไม่ควรใช้ผสมกัน
ความแตกต่างระหว่าง Git Rebase และ Git Merge
ในการทำงานกับ Git ซึ่งเป็นระบบควบคุมเวอร์ชันยอดนิยม นักพัฒนาจะต้องทำงานกับหลายสาขา (branches) อยู่เสมอ เมื่อถึงเวลารวมการเปลี่ยนแปลงจากสาขาหนึ่งไปยังอีกสาขาหนึ่ง Git มีคำสั่งหลักอยู่สองคำสั่งคือ git merge
และ git rebase
ซึ่งแม้จะมีเป้าหมายคล้ายกัน แต่ทำงานต่างกันอย่างสิ้นเชิง
Git Rebase
git rebase
จะใช้การ “ย้าย” commit ทั้งหมดของ branch ที่ต้องการ rebase ไปต่อท้าย branch ที่เป็น target
ตัวอย่าง
ยกตัวอย่างเช่น ถ้าเราต้องการนำ Code ใน feature branch กลับเข้า main branch ด้วยการ rebase ดังรูป
A---B---C main
\
D---E---F feature-branch
เราจะมีขั้นตอนในการ rebase ดังนี้
- เปลี่ยนไปยัง branch เป้าหมายที่ต้องการทำ rebase
หรือ
git checkout main
git switch main
- ทำการ rebase แล้วระบุ branch ที่ต้องการนำกลับเข้ามา
git rebase main
ซึ่งหลังจากทำการ Rebase แล้วเราจะได้ Commit ดังรูป
ก่อน rebase
A---B---C main
\
D---E---F feature
หลัง rebase
A---B---C---D'---E'---F' main
ในระหว่างทางถ้านำ D เข้ามาแล้วเกิด Conflict เราจะต้องแก้ Conflict ให้เสร็จแล้ว Commit กลับเข้าไปก่อน หลังจากนั้นเราจึงจะทำการ rebase ต่อด้วยคำสั่ง
git rebase --continue
ถ้าต้องการจะยกเลิกการ Rebase ให้ใช้คำสั่ง
git rebase --abort
ข้อดีของการ Rebase
- ประวัติดูสะอาดและเป็นเส้นตรง (linear)
- ง่ายต่อการอ่านและเข้าใจว่าแต่ละ commit เกิดขึ้นเมื่อไร
ข้อเสียของการ Rebase
- อาจทำให้เกิดปัญหาในการร่วมงานหากใช้ rebase กับสาขาที่แชร์กับผู้อื่น
- ต้องระวังห้าม rebase สาขาที่ถูก push แล้ว
git merge
การรวม Code ด้วย git merge
จะสร้าง commit พิเศษที่เรียกว่า merge commit เพื่อรวมการเปลี่ยนแปลงทั้งหมดเข้าด้วยกัน(ยกเว้น Fast forward Merge)
ตัวอย่างการ Merge
เหมือนกับตัวอย่างก่อนหน้านี้ ถ้าเราต้องการรวม Code จาก feature-branch กลัยเข้ามายัง main branch
A---B---C main
\
D---E---F feature-branch
เราจะมีขั้นตอนการ merge ดังนี้
- เปลี่ยนไปยัง branch ที่ต้องการ merge code กลับเข้ามา เช่นถ้าต้องการรวม code กลับเข้ามายัง main branch ให้ใช้คำสั่ง
git checkout main
- ต้องการ merge code จาก branch ไหนเข้ามาให้ระบุ branch ที่ต้องการนำ code เข้ามารวมดังนี้ เช่นในกรณีนี้เราต้องการ merge code จาก feature-branch กลับเข้ามาเราจะใช้คำสั่ง
git merge feature-branch
หลังจากที่เราใช้ git merge
จะได้ commit ดังรูป
A---B---C--------G
\ /
D---E---F feature
G คือ Merge commit ที่จะเกิดขึ้นใหม่
ข้อดีของการ Merge
- รักษาประวัติของการพัฒนาทุกขั้นตอน
- ง่ายต่อการดูว่าเกิดการรวมจาก branch ไหนบ้าง
ข้อเสียของการ Merge
- ประวัติ(history) อาจซับซ้อน โดยเฉพาะในโปรเจกต์ขนาดใหญ่ที่มีการ merge หลายครั้ง
สรุปความแตกต่างของ git merge และ git rebase
ความแตกต่าง | Merge | Rebase |
---|---|---|
รูปแบบประวัติ | มี merge commit, มีหลายเส้นทาง | เป็นเส้นตรง, ไม่มี merge commit |
ความง่ายในการติดตาม | ง่ายต่อการดูว่ามีการรวม Code จาก branch ไหน | อ่านง่ายในเชิงลำดับเวลา |
ความเสี่ยง | ต่ำ | สูงถ้าใช้ผิดวิธี (โดยเฉพาะกับ remote branches) |
เหมาะกับ | การรวมงานจากหลายคน | การจัดระเบียบ commit ก่อน merge เข้า main branch หรือก่อนทำ Pull request |
สถาณการณ์ที่เราต้องนำ Code มารวมกัน
สถาณการณ์ต่างๆ ที่เราต้องนำ Code มารวมกันนอกจากการรวม Branch ในตัวอย่างข้างต้นแล้วเรายังมีสถานการณ์ที่ต้องเลือกระหว่าง git rebase
และ git merge
ดังต่อไปนี้
git pull
ตอนที่เรา pull code ลงมาจาก Remote repository ด้วย git pull
git จะทำงาน 2 ขั้นตอนคือ
git fetch
คือการ Download code ล่าสุดลงมาจาก Remote repositoryget merge
หรือgit rebase
(ขึ้นอยู่กับ git config)ในขั้นตอนนี้ git จะทำการรวม Code ที่อยู่ใน Commit ล่าสุดบน Local repository และ Code ล่าสุดที่ fetch ลงมาจาก Remote repository
ซึ่งถ้าตอนติดตั้ง git เราไม่ได้ปรับค่า Config อะไร(กด Next มารัวๆ) เราจะมี git config เป็นแบบนี้
# บน MacOS จะอยู่ใน Global scope ส่วน Windows จะอยู่ใน System scope
[pull]
rebase = false
ซึ่งนั่นหมายความว่าเราเลือกที่จะนำ Code ที่ Fetch ลงมาจาก Remote Repository มารวมกับ Code ใน Local repository ด้วยการ merge เนื่องจากค่า rebase = false
ถ้าเราต้องการให้ git นำ code ลงมารวมกันด้วยการ rebase เราจะต้องกำหนดให้ rebase = true
หรือถ้าเราต้องการใช้ rebase แทนการ merge เราจะกำหนด parameter เข้าไปเพิ่มแบบนี้
git pull --rebase
Fork repository
เช่นเดียวกันการแตก Branch ออก ถ้าเราใช้ Github หรือ Cloud service เจ้าอื่นๆที่ repository อยู่ภายใต้ user เราสามารถเลือกใช้การ Fork แทนการแตก branch ได้ ซึ่งการนำ Code กลับไปรวมกันก็จะใช้การสร้าง Pull request หรือ Merge request