Git มีคำสั่งสามตัวที่ใช้ “ย้อนกลับ” การเปลี่ยนแปลง ได้แก่ git reset, git revert และ git checkout แต่ละคำสั่งมีพฤติกรรมและวัตถุประสงค์ที่แตกต่างกัน การเข้าใจความแตกต่างจะช่วยให้คุณเลือกใช้คำสั่งที่ถูกต้องในแต่ละสถานการณ์ บทความนี้จะอธิบายรายละเอียดของแต่ละคำสั่ง กรณีการใช้งาน และแนวทางปฏิบัติที่ดีเมื่อทำงานกับ Git
git reset: ย้อน History กลับ
git reset ใช้เพื่อย้าย HEAD และ Branch pointer ไปยัง Commit ที่ระบุ โดยมีสามโหมดหลักที่มีพฤติกรรมแตกต่างกัน ขึ้นอยู่กับว่าคุณต้องการเก็บการเปลี่ยนแปลงหรือไม่
# --soft: ย้าย HEAD แต่คงไว้ใน Staging Area
git reset --soft HEAD~1
# --mixed (default): ย้าย HEAD และเคลียร์ Staging Area
git reset HEAD~1
# --hard: ย้าย HEAD, เคลียร์ Staging และ Working Directory
git reset --hard HEAD~1
# รีเซ็ต N commits ก่อนหน้า
git reset --soft HEAD~3
เมื่อไหร่ควรใช้ reset?
- ยกเลิก Commit ล่าสุดบน Branch ส่วนตัว (ที่ยังไม่ได้ Push)
- รวม Commit หลายอันก่อน Push ขึ้น Remote
- เคลียร์ Staging Area ก่อน Commit
- เอาไฟล์บางไฟล์ออกจากการ Commit ล่าสุด
- จัดเรียง History ใหม่ก่อนที่จะแชร์กับทีม
⚠️ คำเตือน: อย่าใช้ git reset --hard บน Branch ที่ Push ไปแล้ว เพราะจะทำให้ History ไม่ตรงกันกับ Remote และอาจสร้างความสับสนให้กับสมาชิกทีม Dot Enterprise แนะนำให้ใช้ git revert แทนในกรณีที่เป็น Shared Branch เพื่อความปลอดภัยของเล็ทหรือ Production Environment
git revert: สร้าง Commit ใหม่เพื่อยกเลิก
git revert สร้าง Commit ใหม่ที่ “ยกเลิก” การเปลี่ยนแปลงของ Commit ที่ระบุ โดยไม่ลบ History เดิม ปลอดภัยกว่า reset สำหรับ Branch ที่แชร์กับทีม และเหมาะสำหรับ Production Release ที่ต้องรักษา Audit Trail
# ยกเลิก Commit ล่าสุด
git revert HEAD
# ยกเลิก Commit ที่ระบุ (ไม่ต้อง Commit อัตโนมัติ)
git revert --no-commit abc1234
# ยกเลิกหลาย Commit
git revert HEAD~3..HEAD
# ยกเลิก Commit โดยไม่เปิด Editor
git revert --no-edit HEAD
เมื่อไหร่ควรใช้ revert?
- ยกเลิก Commit ที่ Push ขึ้น Remote ไปแล้ว
- ต้องการให้ History ครบถ้วน (Audit Trail) สำหรับการตรวจสอบ
- ทำงานบน Shared Branch ร่วมกับทีม
- Rollback ใน Production Branch อย่างปลอดภัย
- ต้องให้ Code Review ของการยกเลิก
เมื่อ Revert ล้มเหลวเพราะ Merge Conflict คุณสามารถใช้ วิธีการแก้ Merge Conflict เพื่อแก้ไข Conflict แล้วจึงสำเร็จ Revert
git checkout: สลับ Branch หรือกู้คืนไฟล์
git checkout มีสองการใช้งานหลัก คือสลับ Branch และกู้คืนไฟล์เดี่ยวจาก Commit เดิม (ไม่เปลี่ยน History) ใน Git รุ่นใหม่ได้มีคำสั่ง git switch และ git restore ที่แยกความหมายออกจากกัน
# สลับ Branch (ใหม่: git switch)
git checkout main
# กู้คืนไฟล์จาก Commit ล่าสุด
git checkout -- filename.txt
# กู้คืนไฟล์จาก Commit ที่ระบุ
git checkout abc1234 -- filename.txt
# Git ใหม่กว่า แนะนำให้ใช้ restore แทน
git restore filename.txt
git restore --source abc1234 filename.txt
# สลับ Branch (Git 2.23+)
git switch main
เมื่อไหร่ควรใช้ checkout?
- ยกเลิกการเปลี่ยนแปลงไฟล์ที่ยังไม่ได้ Stage
- กู้คืนไฟล์บางไฟล์จาก Commit เก่า
- สลับ Branch (แต่แนะนำใช้
git switchแทน) - ตรวจสอบ Code เวอร์ชันเก่า โดยไม่สร้าง Commit ใหม่
หากต้องการกู้คืน Commit ที่ลบไปแล้ว คุณสามารถใช้ git reflog เพื่อกู้คืน Commit ที่หายไป
ตารางเปรียบเทียบโดยละเอียด
| คำสั่ง | เปลี่ยน History? | ปลอดภัยบน Shared Branch? | ตรวจสอบ Remote? | ใช้เมื่อ |
|---|---|---|---|---|
| reset –soft | ใช่ | ไม่ (ถ้า Push แล้ว) | ไม่ | รวม Commit ก่อน Push |
| reset –mixed | ใช่ | ไม่ (ถ้า Push แล้ว) | ไม่ | ยกเลิก Commit บน Local |
| reset –hard | ใช่ (ลบข้อมูล) | ไม่เลย | ไม่ | เริ่มใหม่ทั้งหมดบน Local เท่านั้น |
| revert | ไม่ (สร้าง Commit ใหม่) | ใช่ (แนะนำ) | ใช่ | ยกเลิก Commit ที่ Push แล้ว |
| checkout/restore | ไม่ | ใช่ | ใช่ | กู้คืนไฟล์เดียว |
แนวทางปฏิบัติที่ดีสำหรับทีม
เมื่อทำงานใน Environment ของ Dot Enterprise ที่มีหลายสมาชิก ควรยึดหลักเหล่านี้:
- ใช้
resetเฉพาะบน Feature Branch ของตัวเอง ที่ยังไม่ได้ Push - ใช้
revertเมื่อต้องยกเลิก Commit ที่ Push ไปแล้ว โดยเฉพาะ Main/Develop Branch - สร้าง Pull Request แม้สำหรับ Revert เพื่อให้ทีมทราบและ Review
- ใช้ git commit –amend เพื่อแก้ไข Commit ล่าสุด ก่อน Push
- อ่านเพิ่มเติมเกี่ยวกับ ความแตกต่างของ Reset Modes เพื่อเข้าใจลึกยิ่งขึ้น
สรุป
กฎง่าย ๆ ในการเลือก: ถ้าต้องการยกเลิก Commit ที่ยังอยู่ใน Local ใช้ reset ถ้า Push ไปแล้วหรือทำงานร่วมกับทีมใช้ revert และถ้าต้องการกู้คืนไฟล์เดี่ยวใช้ checkout หรือ restore การเข้าใจความแตกต่างนี้จะช่วยให้คุณจัดการกับข้อผิดพลาดใน Git ได้อย่างมั่นใจและปลอดภัย โดยเฉพาะเมื่อทำงานร่วมกับทีมในโครงการที่มีความสำคัญ
