ในกรณีส่วนใหญ่ Git สามารถรวมความแตกต่างระหว่าง branches และ merge ได้อัตโนมัติ เพราะนักพัฒนามักแก้ไขบรรทัดหรือไฟล์ที่ต่างกัน แต่มีบางกรณีที่ Git ไม่สามารถ merge repository เองได้ เรียกว่า merge conflicts
คู่มือนี้จะอธิบายว่า merge คืออะไร merge conflicts คืออะไร และวิธีแก้ไข git merge conflict เริ่มกันเลย!
Merge Conflict คืออะไร?
Merge conflict คือสถานการณ์ที่ Git ไม่สามารถ merge สอง branches ได้โดยไม่ต้องการความช่วยเหลือจากคุณ
Merges เป็นฟีเจอร์สำคัญของระบบควบคุมเวอร์ชันอย่าง Git ช่วยให้นักพัฒนารักษาเส้นทางพัฒนาแยกกันหลายเส้นใน repository เดียวกัน หมายถึงนักพัฒนาคนหนึ่งแก้บั๊กบน branch หนึ่งโดยไม่ต้องเปลี่ยน main copy ของโปรเจกต์
Merge conflicts เกิดขึ้น 2 สถานการณ์:
- สอง branches แก้ไขบรรทัดโค้ดเดียวกัน
- Branch หนึ่งลบไฟล์ที่ branch อีกอันแก้ไขอยู่
เมื่อ merge conflict เกิดขึ้น Git จะแสดง error บอกว่า merge branches ไม่สำเร็จ
วิธีแก้ไข Conflict กรณีไฟล์ถูกลบ (Removed File Conflict)
Git branches อิสระต่อกัน หมายถึงนักพัฒนาลบไฟล์บน branch หนึ่งได้โดยไม่กระทบอีก branch Merge conflict เกิดขึ้นหากมีการเปลี่ยนแปลงไฟล์บน branch หนึ่ง แต่ไฟล์นั้นถูกลบบนอีก branch Git ไม่รู้ว่าจะลบไฟล์หรือเก็บการเปลี่ยนแปลง
สมมติมี 2 branches: dev และ master บน dev ลบ README.md บน master เพิ่มข้อความใหม่
Merge ด้วยคำสั่ง:
git merge dev
จะ merge branch "dev" เข้ามา branch ปัจจุบัน (master) เกิด merge conflict:
Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result.
ต้องตัดสินใจ: จะเก็บไฟล์ไว้ หรือลบทิ้ง? หากอยากเก็บไฟล์ ใช้ git add เพิ่มกลับ repository:
git add README.md
หากอยากลบ ใช้ git rm:
git rm README.md
rm command จะลบไฟล์จาก local repository ตรวจสอบดีๆ ก่อนใช้
หลังเลือกแล้ว สร้าง commit และ merge branch:
git add README.md git commit -m "feat: Add README.md to repository" git merge dev
git add stage การเปลี่ยนแปลง git commit สร้าง commit ใหม่ git merge merge branches ตอนนี้ merge สำเร็จเพราะ resolve conflict แล้ว
วิธีแก้ไข Conflict กรณีไฟล์ถูกแก้ไขซ้ำ (File Change Conflict)
นักพัฒบางครั้งแก้ไขไฟล์เดียวกันบน 2 branches ต่างกัน Git ไม่แยกได้ว่าจะเก็บการเปลี่ยนแปลงของ branch ไหน เมื่อ merge จะเกิด conflict
สมมติ repository มี 2 branches: master และ dev แก้ไข README.md ทั้งคู่ เกิด conflict:
Auto-merging README.md CONFLICT (content): Merge conflict in README.md Automatic merge failed; fix conflicts and then commit the result.
ขั้นแรก ระบุสาเหตุด้วย git status:
On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: README.md
เห็นว่า README.md ถูกแก้ไขทั้งสอง branches ตอนนี้แก้ไข conflict เปิด README.md ด้วย text editor:
This is a README.md file. This is in a repository called merge-conflicts. <<<<<<< HEAD This file is on the main branch. ======= This file is on the dev branch. >>>>>>> dev
Git แก้ไขไฟล์แจ้ง conflict และเพิ่ม conflict markers ใช้เครื่องหมาย <, >, = แสดงความแตกต่าง:
<(less than) แสดงการเปลี่ยนแปลงบน branch ปัจจุบัน (HEAD/master)>(greater than) แสดงการเปลี่ยนแปลงบน branch ที่ merge เข้ามา (dev)=(equals) แยกความแตกต่าง
ในกรณีนี้:
- "This file is on the main branch." อยู่บน master (HEAD)
- "This file is on the dev branch." อยู่บน dev
แก้ไข conflict: ลบข้อความที่ไม่ต้องการ สมมติอยากให้โค้ดแสดง "This file is on a branch." แก้เป็น:
This is a README.md file. This is in a repository called merge-conflicts. This file is on a branch.
หลังแก้ไขแล้ว Stage, commit และ merge:
git add . git commit -m "feat: Resolve merge conflict." git merge dev
ตอนนี้ merge สำเร็จแล้ว
สรุป
Merge conflicts เกิดเมื่อแก้ไขบรรทัดเดียวกันบน 2 branches หรือแก้ไขไฟล์บน branch หนึ่งและลบไฟล์นั้นบนอีก branch
คู่มือนี้อธิบายวิธีแก้ไขทั้ง 2 กรณี ตอนนี้คุณพร้อมจัดการ merge conflicts อย่างมืออาชีพ Git แล้ว