บางครั้งหลังจาก pull code จากเซิร์ฟเวอร์ application หยุดทำงาน หรือเกิด error ต่างๆ ในสถานการณ์นี้ การระบุว่า pull ครั้งไหนที่ทำให้เสีย และวิธีย้อนกลับที่เร็วและปลอดภัยเป็นสิ่งจำเป็น หากคุณทำงาน Cloud VPS ที่มีทีมพัฒนาหลายคน การแก้ไขปัญหา Broken Pull อย่างรวดเร็วคือกุญแจสำคัญ
Code พังหลังจาก Git Pull: เกิดอะไรขึ้น
เมื่อ pull code แล้ว application เสีย สาเหตุอาจมาจากหลายแหล่ง:
- Syntax Error จากโค้ดใหม่
- Missing Dependencies หรือ Libraries
- Database Migration ที่ยังไม่รัน
- Configuration ที่เปลี่ยน
- Merge Conflict ที่แก้ไมดี
- Breaking Changes จาก dependency update
- Environment Variables ที่ขาด
สิ่งสำคัญคือการ rollback ให้รวดเร็วเพื่อ restore service ให้กลับมาทำงานได้อย่างปกติ
ขั้นตอน 1: ระบุปัญหา
ก่อนอื่น ต้องระบุให้แน่ใจว่า pull ล่าสุดเป็นสาเหตุ
# ดูเหมือนว่า pull ล่าสุดทำให้ code พัง ตรวจสอบด้วย log
git log --oneline -10
# Output:
# a1b2c3d Merge pull request #234: Add new feature
# 5e6f7g8h Update authentication
# z9x8w7v6 Fix database connection
# ...
# ดูว่าใครรับผิดชอบและเปลี่ยนแปลงอะไร
git show a1b2c3d
ตรวจสอบ Error Messages
- ดู logs ของ application
- ตรวจสอบ console errors
- ลอง run application locally
- Check ว่า dependency ติดตั้งครบหรือไม่
วิธี 1: ใช้ git reflog (ปลอดภัยที่สุด)
reflog เก็บประวัติการเปลี่ยนแปลง HEAD ทั้งหมด ซึ่งเป็นวิธีที่ปลอดภัยที่สุดในการ rollback เพราะมันจำ state ก่อนหน้าได้
# ดูประวัติการเปลี่ยนแปลง HEAD
git reflog
# Output จะแสดงประมาณนี้:
a1b2c3d HEAD@{0}: pull: Fast-forward
5e6f7g8h HEAD@{1}: commit: Add new feature
z9x8w7v6 HEAD@{2}: pull: Merge made by recursive strategy
y8x7w6v5 HEAD@{3}: commit: Previous work
x7w6v5u4 HEAD@{4}: checkout: moving from main to feature-branch
# ข้อมูล HEAD@{0} = state ปัจจุบัน
# ข้อมูล HEAD@{1} = state ก่อนหน้า
# เลือก HEAD ref ที่ก่อน pull ที่ทำให้พัง
# สมมุติว่า HEAD@{1} คือ state ที่ดี
git reset --hard HEAD@{1}
# ตรวจสอบว่า rollback สำเร็จ
git log --oneline -3
ข้อดีของ git reflog
- ปลอดภัย – ไม่ลบ commit จริงๆ เพียงแค่เปลี่ยน pointer
- Recoverable – ถ้าย้อนกลับผิดพลาด สามารถกลับได้
- รวดเร็ว – ไม่ต้องดู branch ต่างๆ
- ประวัติครบถ้วน – เก็บทุก operation ของ HEAD
วิธี 2: ใช้ git reset –hard (ต้องระวัง)
ถ้าคุณรู้ commit ID ของสถานะก่อนหน้า ก็สามารถ reset ตรงไปที่นั่นได้
# reset ไปที่ commit ที่รู้ว่าทำงานปกติ
git reset --hard 5e6f7g8h
# ตรวจสอบ
git log --oneline -1
# สิ่งที่ reset --hard ทำ:
# 1. เปลี่ยน HEAD ไปยัง commit นั้น
# 2. Update staging area
# 3. Update working directory
# 4. ลบ uncommitted changes ทั้งหมด
เตือน: git reset –hard ไม่สามารถกู้คืนได้
ระวัง! git reset –hard จะลบ uncommitted changes ทั้งหมดโดยไม่มีทางกู้คืน ถ้าคุณมี uncommitted work ที่สำคัญ ให้ save เป็น stash ก่อน
# ถ้าคุณมี uncommitted changes ที่สำคัญ
# Save เป็น stash ก่อน
git stash
# จากนั้น reset
git reset --hard 5e6f7g8h
# ถ้าต้องการ apply stash กลับ
git stash pop
วิธี 3: สร้าง Fix Branch แทน (ปลอดภัยกว่า)
ถ้าต้องการให้ทีมรู้และ review ก่อนย้อนกลับ ลองสร้าง fix branch แทน
# สร้าง branch ใหม่จากก่อน pull (state ที่ดี)
git checkout -b fix/broken-pull 5e6f7g8h
# ตรวจสอบให้แน่ใจว่าทำงาน
npm install
npm run dev
# test application ให้แน่ใจ
# จากนั้นสร้าง PR เพื่อให้ทีม review
git push origin fix/broken-pull
# ที่ GitHub/GitLab สร้าง Pull Request
# Title: "Revert: Fix broken pull from feature X"
# Description: อธิบายว่าทำไมต้อง revert
ข้อดีของวิธีนี้
- ทีมรู้ว่าเกิดปัญหา
- มีเวลาว่างสำหรับ review
- ประวัติ Git ชัดเจน
- สามารถหา root cause ได้ต่อ
วิธี 4: Revert Specific Commit (บ่งบอก history)
ถ้า pull มี commit หลายตัว แต่ต้องการลบแค่ commit ที่เป็นปัญหา ให้ใช้ git revert
# Revert specific commit
git revert
# Example: ถ้า commit a1b2c3d ทำให้พัง
git revert a1b2c3d
# Git จะ:
# 1. สร้าง commit ใหม่ที่ย้อนกลับการเปลี่ยนแปลง
# 2. เก็บ history เดิมไว้
# 3. ทำให้ชัดเจนว่าเกิด revert ขึ้น
# ถ้า revert มี conflict ให้แก้ไข
# จากนั้น
git add .
git revert --continue
ข้อต่างระหว่าง Revert vs Reset
- Revert: สร้าง commit ใหม่ที่ย้อนการเปลี่ยนแปลง เก็บ history ทั้งหมด ดี for shared branches
- Reset: ลบ commits โดยเปลี่ยน HEAD pointer ไม่เก็บ history ดี for local branches
ขั้นตอน 5: ขั้นตอนทีละขั้น Rollback
# ขั้นที่ 1: ตรวจสอบสถานการณ์
git status
git log --oneline -5
# ขั้นที่ 2: ดู reflog เพื่อเลือก safe state
git reflog
# ขั้นที่ 3: Reset ไปที่ state ที่ดี
git reset --hard HEAD@{1}
# ขั้นที่ 4: ตรวจสอบว่า reset สำเร็จ
git log --oneline -1
git status
# ขั้นที่ 5: Restart application
# npm install (ถ้า package.json เปลี่ยน)
# npm run dev
# ขั้นที่ 6: Force push (ถ้า shared branch ต้องระวัง)
# โดยปกติอย่า force push ไป main
# แต่ถ้า feature branch อาจจำเป็น
git push origin --force
ขั้นตอน 6: สื่อสารกับทีม
- บอกทีมทันที – ว่า pull นั้นมีปัญหา
- อธิบายปัญหา – error message อะไร
- บอกแผนการแก้ไข – rollback ไป state ไหน
- ส่ง Alert – ถ้าเป็นวาระสำคัญ notify ทั้งทีม
- Post-Mortem – หลังจาก fix ร่วม review เพื่อหา root cause
Prevention: วิธีป้องกันไม่ให้เกิด Broken Pull
ก่อน Push Code
- ทดสอบ Code ให้ครอบคลุม – Unit tests, integration tests, manual testing
- Run Linter และ Type Checker – npm run lint, typescript check
- ตรวจสอบ Dependencies – npm install, bundle size
- Test สำหรับ Breaking Changes – ถ้า upgrade dependency
Using CI/CD Pipeline
- Automatic Testing – แทนที่จะ manual ทุกครั้ง
- Pre-commit Hooks – Run linter ก่อน commit
- Pre-push Hooks – Run tests ก่อน push
- Pull Request Checks – ต้องผ่าน CI ก่อน merge
Code Review Process
- Require Code Review – ไม่ให้ merge เดียวเอง
- Test PR Locally – Reviewer ควร checkout และ test
- Review Tests – ตรวจสอบว่า tests ครอบคลุม
- Ask Questions – ถ้าไม่เข้าใจ logic
Rollback Checklist
Before Rollback:
- [ ] ระบุว่า commit ไหนสาเหตุ
- [ ] ซ่อม uncommitted changes เป็น stash
- [ ] Notify ทีม
- [ ] ถ่ายภาพ log ปัจจุบัน
During Rollback:
- [ ] ใช้ git reflog เลือก safe state
- [ ] git reset --hard HEAD@{X}
- [ ] ตรวจสอบ git status
- [ ] Restart application
- [ ] Test functionality
After Rollback:
- [ ] Confirm กับทีม
- [ ] แสดง what went wrong
- [ ] Plan fix ที่ถูกต้อง
- [ ] Find root cause
- [ ] Update documentation
ตัวอย่าง Real-World: Rollback Broken Pull
# Scenario: Deploy นาทีที่ผ่านมา API ล้ม
# Step 1: ตรวจสอบ
$ git log --oneline -5
a1b2c3d Merge pull request #456: Upgrade to Node 20
5e6f7g8h Update dependencies
z9x8w7v6 Add auth middleware
y8x7w6v5 Previous stable state
# Step 2: เห็น a1b2c3d merge ใหม่ ลองดู
$ git show a1b2c3d
# เห็นว่า package.json เปลี่ยนแปลง breaking change
# Step 3: ดู reflog
$ git reflog
a1b2c3d HEAD@{0}: pull: Fast-forward
5e6f7g8h HEAD@{1}: commit: Update dependencies
# Step 4: Reset ไป HEAD@{1}
$ git reset --hard HEAD@{1}
HEAD is now at 5e6f7g8h Update dependencies
# Step 5: ตรวจสอบ
$ npm install
$ npm run dev
# API ทำงานดี!
# Step 6: Notify Slack
# "@channel Rollback complete. API restored. Node 20 upgrade needs more testing."
# Step 7: ทีมจะ create new branch เพื่อ fix ต่อ
$ git checkout -b fix/node20-upgrade
สรุป: รู้วิธีย้อนกลับจะช่วยให้ปลอดภัย
รู้วิธีย้อนกลับจะช่วยให้คุณกลับเข้าหา safe state ได้อย่างรวดเร็ว ไม่ว่าจะใช้ reflog, reset, หรือ revert แต่ละวิธีมีข้อดี-ข้อเสียของตัวเอง ก่ที่ pull code ใหม่ที่ใจเย็น test ให้แน่ใจก่อน และมี CI/CD pipeline ที่ดีจะช่วยป้องกันปัญหา Broken Pull ได้ล่วงหน้า หากทำงานบน Cloud VPS ที่ critically important ก็ควรมี backup plan และสื่อสารกับทีมอยู่เสมอ
