ย้อนกลับการเปลี่ยนแปลงใน GitHub! คู่มือการใช้ reset, revert, checkout สำหรับผู้เริ่มต้น
ในบทความที่ผ่านมา เราได้เรียนรู้วิธีการใช้ `git add` และ `git commit` เพื่อบันทึกการเปลี่ยนแปลงของไฟล์ แต่ในการพัฒนาย่อมมีข้อผิดพลาดเกิดขึ้นเสมอ "แย่แล้ว, คอมมิตไฟล์ผิด!" หรือ "อยากกลับไปเวอร์ชันก่อนหน้านี้..." เป็นเรื่องที่เกิดขึ้นได้เป็นประจำ
ความแข็งแกร่งของ Git คือการมีฟังก์ชันที่สามารถยกเลิกข้อผิดพลาดเหล่านี้ได้อย่างปลอดภัยและง่ายดาย ในบทความนี้ เราจะอธิบายถึงความแตกต่างและการใช้งานของ 3 คำสั่งหลักในการ "ย้อนกลับ" การเปลี่ยนแปลง ได้แก่ `git checkout`, `git reset`, และ `git revert` อย่างละเอียดตามสถานการณ์ต่างๆ หากคุณเชี่ยวชาญคำสั่งเหล่านี้แล้ว ก็ไม่จำเป็นต้องกลัวการทำผิดพลาดอีกต่อไป!
3 คำสั่ง "ย้อนกลับ": จะใช้คำสั่งไหนเมื่อไหร่?
Git มีคำสั่งในการย้อนกลับการเปลี่ยนแปลงอยู่หลายคำสั่ง ซึ่งอาจทำให้ผู้เริ่มต้นสับสนได้ง่าย ก่อนอื่น เรามาทำความเข้าใจบทบาทและการใช้งานของแต่ละคำสั่งกันแบบง่ายๆ
git checkout: ใช้เมื่อต้องการย้อนกลับการเปลี่ยนแปลงในไดเรกทอรีทำงาน โดยที่ยังไม่ได้คอมมิต เหมาะสำหรับสถานการณ์ที่ว่า "การเปลี่ยนแปลงในไฟล์นี้ ไม่เอาทั้งหมดแล้ว!"git reset: ใช้เมื่อต้องการยกเลิกคอมมิตใน local repository ที่ยังไม่ได้ push เป็นคำสั่งที่มีประสิทธิภาพในการทำให้คอมมิต "เหมือนไม่เคยเกิดขึ้น" แต่เนื่องจากเป็นการเขียนประวัติศาสตร์ใหม่ จึงไม่ควรใช้กับ remote repository ที่แชร์กับผู้อื่นแล้วgit revert: ใช้เมื่อต้องการยกเลิกคอมมิตที่ push ไปแล้วและเป็นสาธารณะ ไม่ใช่การลบคอมมิต แต่เป็นการสร้าง "คอมมิตใหม่ที่หักล้างเนื้อหาของคอมมิตที่ระบุ" เป็นวิธีที่ปลอดภัยในการแก้ไขประวัติศาสตร์ จึงเป็นคำสั่งที่จำเป็นอย่างยิ่งในการพัฒนาแบบทีม
ถ้าจะให้เห็นภาพ `reset` เหมือนกับการ "ย้อนเวลากลับไปในอดีตเพื่อลบอนาคต (คอมมิต)" ในขณะที่ `revert` เหมือนกับการ "ออกบทความใหม่เพื่อแก้ไขข้อผิดพลาดในอดีต"
ปฏิบัติจริง! ขั้นตอนการ "ย้อนกลับ" ตามสถานการณ์
ต่อไป เรามาดูวิธีใช้แต่ละคำสั่งตามสถานการณ์จริงกัน
กรณีที่ 1: ต้องการยกเลิกการเปลี่ยนแปลงที่กำลังทำอยู่ โดยยังไม่ได้คอมมิต (`checkout`)
เป็นกรณีที่คุณลองแก้ไขไฟล์แล้ว แต่คิดว่า "ไม่เอาการเปลี่ยนแปลงนี้ทั้งหมดแล้วดีกว่า" นี่เป็นวิธีที่ง่ายที่สุดในการย้อนกลับการเปลี่ยนแปลงก่อนที่จะทำการ staging
ขั้นแรก ลองแก้ไขไฟล์เพื่อฝึกฝน จากนั้นเมื่อตรวจสอบด้วย `git status` จะพบว่าไฟล์แสดงสถานะเป็น "modified" หากต้องการยกเลิกการเปลี่ยนแปลงนี้ ให้รันคำสั่งต่อไปนี้
git checkout -- [ชื่อไฟล์]
ตัวอย่างเช่น หากต้องการยกเลิกการเปลี่ยนแปลงในไฟล์ `index.html` จะเป็นดังนี้
git checkout -- index.html
เมื่อรันคำสั่งนี้ ไฟล์ที่ระบุจะกลับสู่สถานะของคอมมิตล่าสุดอย่างสมบูรณ์ ข้อควรระวัง: การเปลี่ยนแปลงที่ถูกลบด้วยวิธีนี้ไม่สามารถกู้คืนได้!
กรณีที่ 2: ต้องการยกเลิกคอมมิตล่าสุด (ที่ยังไม่ได้ push) (`reset`)
เป็นกรณีที่ "คอมมิตไปแล้ว แต่เพิ่งรู้ว่าทำผิด!" ซึ่งเป็นความผิดพลาดในเครื่องที่ยังไม่ได้แชร์ให้ใคร (ยังไม่ได้ push) คำสั่ง `reset` มีหลายออปชัน แต่เราจะแนะนำอันที่ใช้บ่อย
ขั้นแรก ใช้ `git log --oneline` เพื่อตรวจสอบประวัติคอมมิต และให้แน่ใจว่าคอมมิตที่ต้องการยกเลิกอยู่บนสุด
git log --oneline
ออปชันที่ 1: --soft (ยกเลิกเฉพาะคอมมิต แต่เก็บการเปลี่ยนแปลงไว้)
ใช้เมื่อต้องการยกเลิกเฉพาะคอมมิตล่าสุด และต้องการให้เนื้อหาการเปลี่ยนแปลงนั้นยังคงอยู่ใน staging area เหมาะสำหรับกรณีที่ "เขียนข้อความคอมมิตผิด"
git reset --soft HEAD^
ออปชันที่ 2: --mixed (ยกเลิกคอมมิตและการ staging)
ใช้เมื่อต้องการยกเลิกคอมมิตล่าสุดและนำการเปลี่ยนแปลงกลับไปยัง working directory ซึ่งเป็นพฤติกรรมปกติของคำสั่ง `reset` เหมาะสำหรับกรณี "ลืมเพิ่มไฟล์" ทำให้สามารถรีเซ็ตแล้ว `add` และ `commit` ใหม่อีกครั้ง
git reset --mixed HEAD^
ออปชันที่ 3: --hard (ลบคอมมิตและการเปลี่ยนแปลงทั้งหมดอย่างถาวร)
ใช้เมื่อต้องการลบคอมมิตล่าสุดและการเปลี่ยนแปลงนั้นให้หายไปโดยสิ้นเชิง เป็นคำสั่งที่อันตรายเพราะการเปลี่ยนแปลงไฟล์จะไม่สามารถกู้คืนได้ ดังนั้นควรใช้ด้วยความระมัดระวังอย่างยิ่ง
git reset --hard HEAD^
HEAD^ หมายถึง "คอมมิตก่อนหน้าหนึ่งอัน" หากต้องการย้อนกลับไป 2 คอมมิต ให้ระบุเป็น `HEAD^^` หรือ `HEAD~2`
กรณีที่ 3: ต้องการยกเลิกคอมมิตที่ push ไปแล้ว (`revert`)
หากทำงานเป็นทีม การใช้ `reset` เพื่อลบคอมมิตที่ push ไปแล้วจะทำให้ประวัติของคนอื่นเกิดความขัดแย้งและสร้างความสับสนอย่างมาก ดังนั้น หากต้องการยกเลิกคอมมิตที่เผยแพร่ไปแล้ว ต้องใช้ `revert` เท่านั้น
`revert` จะสร้าง "คอมมิตใหม่" ที่หักล้างเนื้อหาของคอมมิตที่ระบุโดยอัตโนมัติ เป็นวิธีที่ปลอดภัยในการแก้ไขประวัติโดยไม่ลบประวัติเดิม แต่เป็นการเพิ่มประวัติใหม่เพื่อแก้ไขข้อผิดพลาด
ขั้นแรก ใช้ `git log` เพื่อตรวจสอบ ID (hash) ของคอมมิตที่ต้องการยกเลิก
git log
คัดลอก hash ของคอมมิตที่ต้องการยกเลิก (เช่น `1a2b3c4d`) แล้วรันคำสั่งต่อไปนี้
git revert 1a2b3c4d
เมื่อรันคำสั่ง หน้าจอแก้ไขข้อความคอมมิตจะเปิดขึ้นมา หากคุณพอใจกับข้อความเริ่มต้น ก็สามารถบันทึกและปิดได้เลย จากนั้น "คอมมิตสำหรับยกเลิก" จะถูกสร้างขึ้น สุดท้ายให้ `push` คอมมิตนั้นเพื่อให้การแก้ไขถูกสะท้อนไปยัง remote repository
【โค้ดตัวอย่างที่ใช้งานได้จริง】สำหรับฝึกฝน
เพื่อให้การฝึกใช้คำสั่ง Git ง่ายขึ้น การมีไฟล์ที่สามารถแก้ไขได้จริงย่อมสะดวกกว่า บันทึกโค้ด HTML ต่อไปนี้เป็นไฟล์ชื่อ `practice.html` แล้วลองใช้คำสั่ง `add`, `commit`, `checkout`, `reset` กับไฟล์นี้ดู
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8">
<title>หน้าสำหรับฝึกฝน Git</title>
<style>
body { font-family: sans-serif; text-align: center; margin-top: 50px; }
.box { width: 200px; height: 200px; margin: 20px auto; border: 2px solid #333; display: flex; justify-content: center; align-items: center; font-size: 1.5rem; }
.box.red { background-color: #ffcccc; }
.box.blue { background-color: #cceeff; }
button { padding: 10px 20px; font-size: 1rem; cursor: pointer; }
</style>
</head>
<body>
<h1>ฝึกฝนการใช้ Git</h1>
<div id="colorBox" class="box">ข้อความที่นี่</div>
<button id="changeColorBtn">เปลี่ยนสี</button>
<script>
const colorBox = document.getElementById('colorBox');
const changeColorBtn = document.getElementById('changeColorBtn');
changeColorBtn.addEventListener('click', () => {
if (colorBox.classList.contains('red')) {
colorBox.classList.remove('red');
colorBox.classList.add('blue');
colorBox.textContent = 'เปลี่ยนเป็นสีน้ำเงิน!';
} else {
colorBox.classList.remove('blue');
colorBox.classList.add('red');
colorBox.textContent = 'เปลี่ยนเป็นสีแดง!';
}
});
</script>
</body>
</html>
สรุป: เลือกใช้คำสั่งที่เหมาะสมกับสถานการณ์
สุดท้ายนี้ สรุปการใช้งาน 3 คำสั่งสำหรับย้อนกลับการเปลี่ยนแปลงแบบง่ายๆ
- ยกเลิกการเปลี่ยนแปลงที่ยังไม่ได้คอมมิต →
git checkout -- [ชื่อไฟล์] - ยกเลิกคอมมิตในเครื่อง →
git reset [ออปชัน] HEAD^ - ยกเลิกคอมมิตที่เผยแพร่ไปแล้ว →
git revert [ID ของคอมมิต]
หากคุณใช้ 3 คำสั่งนี้ได้อย่างคล่องแคล่ว ก็ไม่จำเป็นต้องกลัวการทำผิดพลาดใน Git อีกต่อไป ขอให้สนุกกับการเขียนโค้ดและคอมมิตอย่างสบายใจ!