เมื่อสองคน (หรือมากกว่า) ทำงานบน branch เดียวกันใน Git ระบบจะเกิดความท้าทายและปัญหาต่างๆ ที่อาจทำให้งานสูญหาย การรู้วิธีจัดการปัญหาเหล่านี้เป็นสิ่งสำคัญสำหรับการทำงานเป็นทีม บทความนี้จะอธิบายปัญหาทั่วไป วิธีแก้ไข และ best practices ในการทำงานร่วมกันอย่างมีประสิทธิภาพ
ปัญหาทั่วไปเมื่อทำงานร่วมกันบน Branch เดียว
เมื่อสองคนทำงานบน branch เดียวกัน จะเกิดปัญหาต่างๆ ที่อาจทำให้งานเสียหายหรือสูญเสีย ต่อไปนี้คือปัญหาที่พบบ่อยที่สุดและวิธีการจัดการ
ปัญหา #1: Push Rejection (Non-Fast-Forward Error)
สถานการณ์ที่เกิดขึ้นบ่อยครั้ง:
- คนที่ 1 ทำการ commit และ push ขึ้นไป
- คนที่ 2 ยังไม่ทำการ pull จากเซิร์ฟเวอร์
- คนที่ 2 พยายาม push โดยคนที่ 1 ได้ push ไปแล้ว
- Git ปฏิเสธการ push เพราะ branch บนเซิร์ฟเวอร์มี commit ใหม่ที่ไม่มีใน local repository ของคนที่ 2
Error message ที่จะเห็น:
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'origin'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g. 'git pull')
hint: before pushing again.
วิธีแก้: ต้อง pull ข้อมูลล่าสุดก่อนเสมอ
git pull origin branch-name
git push origin branch-name
คำสั่ง pull จะดึง commits ที่ใหม่ที่สุดจากเซิร์ฟเวอร์มา และ merge เข้าไปใน local branch ของคุณ หากไม่มี conflict จะ merge โดยอัตโนมัติ
ปัญหา #2: Merge Conflict
นี่คือปัญหาที่ซับซ้อนกว่า เกิดขึ้นเมื่อทั้งสองคนแก้ไขบรรทัดเดียวกันในไฟล์เดียวกัน Git ไม่สามารถ merge อัตโนมัติได้เพราะไม่รู้ว่าเวอร์ชันไหนถูกต้อง
ตัวอย่างสถานการณ์:
- คนที่ 1 แก้ไขบรรทัด 5 ในไฟล์ config.js เป็น const API_URL = “https://api1.example.com”
- คนที่ 2 แก้ไขบรรทัด 5 เดียวกันเป็น const API_URL = “https://api2.example.com”
- เมื่อคนที่ 2 ทำการ pull หลังจากคนที่ 1 push ไปแล้ว Git จะพบ conflict
$ git pull origin main
AUTO_MERGING src/config.js
CONFLICT (content): Merge conflict in src/config.js
Automatic merge failed; fix conflicts and then commit the result.
เมื่อเปิดไฟล์ config.js จะเห็นเนื้อหา conflict marker:
<<<<<<< HEAD
const API_URL = "https://api1.example.com";
=======
const API_URL = "https://api2.example.com";
>>>>>>> origin/main
วิธีแก้ Merge Conflict:
- เปิดไฟล์ที่มี conflict ด้วย text editor
- แก้ไขส่วนที่ conflict โดยเลือกเวอร์ชันที่ถูกต้อง หรือรวมทั้งสองเวอร์ชัน
- ลบ conflict markers (<<<<<<< HEAD, =======, >>>>>>> origin/main)
- บันทึกไฟล์
- Stage และ commit การแก้ไข
# หลังจากแก้ไขไฟล์แล้ว
git add src/config.js
git commit -m "Resolve merge conflict in config.js: use api1.example.com after discussion with team"
หมายเหตุ: บางครั้งสามารถใช้ merge tools เช่น VS Code, Sublime Text, หรือ GitKraken เพื่อแก้ไข conflict ได้ง่ายกว่า
ปัญหา #3: Lost Work / Overwriting Changes
นี่คือปัญหาที่เลวร้ายที่สุด เมื่อคนที่ 2 ลืม pull ข้อมูลล่าสุด และทำการ force push โดยใช้ flag -f หรือ –force work ของคนที่ 1 อาจสูญหาย
สถานการณ์ที่เสี่ยง:
- คนที่ 1 push commit abc123 ที่ลบ function oldAPI() และเพิ่ม function newAPI()
- คนที่ 2 ยังทำงานกับ local copy เก่าที่มี function oldAPI() อยู่
- คนที่ 2 ทำการ force push โดยไม่ pull ก่อน
- commit abc123 ของคนที่ 1 จะถูก overwrite และ newAPI() function จะหายไป
วิธีป้องกัน: ห้ามใช้ force push บนทั่วไป โดยเฉพาะถ้าเป็น shared branch ที่มีคนอื่นทำงานด้วย
# AVOID - ห้ามใช้บน shared branches
git push -f origin main
git push --force origin main
# SAFER - ใช้ --force-with-lease เพื่อให้ safe ขึ้น
git push --force-with-lease origin branch-name
flag –force-with-lease จะ reject push หากมี commit ใหม่บนเซิร์ฟเวอร์ที่คุณไม่รู้จัก ช่วยป้องกันการสูญหาย work ของคนอื่น
ปัญหา #4: Stale Branch Information
บางครั้งข้อมูล remote branch บน local machine ของคุณอาจเก่า ทำให้คิดว่า branch ยังไม่มี commits ใหม่ แต่จริงๆ แล้วมี commits ใหม่บนเซิร์ฟเวอร์
วิธีแก้: ใช้ fetch เพื่ออัปเดตข้อมูล remote tracking branches
# ดึงข้อมูล remote ล่าสุดโดยไม่ merge
git fetch origin
# ดู commits ล่าสุดบน remote branch
git log origin/main
# ดู status เทียบกับ remote
git status
1. Always Pull Before Push
นี่คือกฎสำคัญที่สุด ทุกครั้งก่อนทำการ push ต้อง pull ข้อมูลล่าสุดจากเซิร์ฟเวอร์ก่อนเสมอ
# Workflow ที่ถูกต้อง
git status # ตรวจสอบสถานะ
git add . # Stage changes
git commit -m "Description" # Commit
git pull origin main # Pull ข้อมูลล่าสุด
# หากมี conflict ให้แก้ไข
git push origin main # Push ขึ้นไป
2. ใช้ Feature Branch แทน Shared Branches
best practice ที่สำคัญคือ ให้แต่ละคนสร้าง feature branch ของตนเอง ห้ามทำงานโดยตรงบน main หรือ master branch
# สำหรับคนที่ 1 - ทำ feature user authentication
git checkout -b feature/user-auth
# ทำงาน commit ต่างๆ
git push origin feature/user-auth
# สำหรับคนที่ 2 - ทำ feature payment integration
git checkout -b feature/payment
# ทำงาน commit ต่างๆ
git push origin feature/payment
ด้วยวิธีนี้ branch หลักจะปลอดภัย และปัญหา merge conflict จะลดลงมาก
3. Communicate และ Coordinate ระหว่างสมาชิกทีม
การสื่อสารที่ดีคือสิ่งสำคัญ บอกให้ทีมรู้:
- คุณกำลังทำอะไรใน branch ไหน
- ไฟล์ไหนที่คุณกำลังแก้ไข เพื่อไม่ให้คนอื่นแก้ไขไฟล์เดียวกัน
- ประมาณเวลาที่จะ commit และ push
- หากใกล้จะ merge branch ลงมา main บอกให้ทีมรู้ก่อน
ใช้ tools เช่น Slack, Discord, หรือ project management tools เพื่อประสานงานกับทีม
4. ใช้ Pull Request (PR) และ Code Review
นี่คือ best practice ที่นิยมใช้ในทีมมืออาชีพ PR ช่วยให้:
- สมาชิกอื่นสามารถรีวิว code ของคุณก่อน merge
- ลดความเสี่ยงของ bug หรือ broken code ใน main branch
- สร้าง discussion เกี่ยวกับการออกแบบ implementation
- เพิ่มเติม documentation และ context ของการเปลี่ยนแปลง
# Workflow ด้วย PR
1. สร้าง feature branch
git checkout -b feature/new-api
2. ทำงาน commit
git add .
git commit -m "Implement new API endpoint"
3. Push ขึ้นไป
git push origin feature/new-api
4. สร้าง PR จาก GitHub/GitLab web interface
- Add description ที่ชัดเจน
- Request reviewers
5. รอการ approve จากอย่างน้อย 1 reviewer
6. Merge PR (โดยทั่วไปใช้ Squash or Rebase merge)
5. ทำ Rebase หรือ Squash Commits ก่อน Merge
เมื่อก่อน merge feature branch ลงมา main ให้ clean up commit history ทำให้สามารถเข้าใจการเปลี่ยนแปลงได้ง่ายขึ้น
# Squash commits เป็น 1 commit เดียว
git rebase -i HEAD~3 # Interactive rebase 3 commits ล่าสุด
# หรือ squash ขณะ merge PR
# สำหรับ GitHub: เลือก "Squash and merge" ในปุ่ม merge
Recommended Complete Workflow
นี่คือ workflow ที่ recommended สำหรับทีมที่ทำงานกับ ผู้ให้บริการโฮสติ้ง Cloud VPS หรือ server อื่นๆ
# 1. สร้าง feature branch จาก main ล่าสุด
git checkout main
git pull origin main
git checkout -b feature/my-feature
# 2. ทำงาน และ commit เพียงสองสามครั้ง
git add src/myfile.js
git commit -m "Add user validation logic"
# 3. ตรวจสอบว่า main มี commits ใหม่ไหม
git fetch origin
git log --oneline main..origin/main
# 4. หากมี commits ใหม่ ให้ rebase feature branch
git rebase origin/main
# 5. Push feature branch ขึ้นไป
git push origin feature/my-feature
# 6. สร้าง Pull Request บน GitHub/GitLab
# เพิ่มรายละเอียด description ที่ชัดเจน
# 7. รอการ approve จากทีม
# 8. Squash and merge PR
# 9. ลบ feature branch เก่า
git branch -d feature/my-feature
git push origin --delete feature/my-feature
ใช้ Git Hooks สำหรับ Automation
บน ผู้ให้บริการโฮสติ้ง VPS สามารถตั้งค่า git hooks เช่น pre-commit เพื่อรัน tests โดยอัตโนมัติ ก่อน commit
# ตัวอย่าง .git/hooks/pre-commit
#!/bin/bash
echo "Running tests..."
npm test
if [ $? -ne 0 ]; then
echo "Tests failed. Commit aborted."
exit 1
fi
Stash Changes ชั่วคราว
หากคุณอยากเปลี่ยน branch แต่ยังไม่พร้อมจะ commit ใช้ git stash
# บันทึกการเปลี่ยนแปลงชั่วคราว
git stash
# เปลี่ยน branch
git checkout main
# หลังจาก pull ข้อมูลใหม่ กลับไป feature branch
git checkout feature/my-feature
# คืนการเปลี่ยนแปลง
git stash pop
ตั้งค่า .gitignore ให้เหมาะสม
โปรแกรมที่ generate files อัตโนมัติ (node_modules, .env, build files) ไม่ควร commit ให้เพิ่มลงใน .gitignore
# .gitignore
node_modules/
.env
.env.local
dist/
build/
*.log
.DS_Store
สรุป
การทำงานร่วมกันบน branch เดียวกันต้องการ discipline, communication, และ best practices ที่ดี หากทำตามขั้นตอนดังกล่าว ปัญหาส่วนใหญ่สามารถป้องกันได้ เมื่อเกิด conflict ให้แก้ไขอย่างรอบคอบ และสื่อสารกับสมาชิกทีมเสมอ
