Coding Gun

git rebase vs git merge

ทั้ง git rebase และ git merge ต่างก็เป็นคำสั่งที่เราใช้ในการรวม Code ซึ่งการนำ Code ที่แตกต่างกัน 2 ฃุดมารวมกันเราจะเลือกได้ 2 วิธีคือ ดังรูป

git rebase vs git merge

  1. git rebase คือการนำ Commit แต่ละตัวมาใส่ใน branch ปัจจุบัน(Move) ซึ่งการ Rebase จะไม่มี Commit ใหม่

    git rebase

  2. git merge คือการนำ Code ที่แตกต่างกัน 2 ชุดมารวมกัน(Combine) ดังนั้นการใช้ git merge จะทำให้เกิด Commit ใหม่

    git merge

เราควรเลือก 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 ดังนี้

  1. เปลี่ยนไปยัง branch เป้าหมายที่ต้องการทำ rebase
    git checkout main
    
    หรือ
    git switch main
    
  2. ทำการ 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

ข้อเสียของการ Rebase

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 ดังนี้

  1. เปลี่ยนไปยัง branch ที่ต้องการ merge code กลับเข้ามา เช่นถ้าต้องการรวม code กลับเข้ามายัง main branch ให้ใช้คำสั่ง
    git checkout main
    
  2. ต้องการ 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

ข้อเสียของการ 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 ขั้นตอนคือ

  1. git fetch คือการ Download code ล่าสุดลงมาจาก Remote repository
  2. get 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

อ่านวิธีการใช้งาน Merge และ Rebase ต่อได้ที่

Phanupong Permpimol
Follow me