🇯🇵 日本語 | 🇺🇸 English | 🇪🇸 Español | 🇵🇹 Português | 🇹🇭 ไทย | 🇨🇳 中文

ย้อนกลับการเปลี่ยนแปลงใน GitHub! คู่มือการใช้ reset, revert, checkout สำหรับผู้เริ่มต้น

ในบทความที่ผ่านมา เราได้เรียนรู้วิธีการใช้ `git add` และ `git commit` เพื่อบันทึกการเปลี่ยนแปลงของไฟล์ แต่ในการพัฒนาย่อมมีข้อผิดพลาดเกิดขึ้นเสมอ "แย่แล้ว, คอมมิตไฟล์ผิด!" หรือ "อยากกลับไปเวอร์ชันก่อนหน้านี้..." เป็นเรื่องที่เกิดขึ้นได้เป็นประจำ

ความแข็งแกร่งของ Git คือการมีฟังก์ชันที่สามารถยกเลิกข้อผิดพลาดเหล่านี้ได้อย่างปลอดภัยและง่ายดาย ในบทความนี้ เราจะอธิบายถึงความแตกต่างและการใช้งานของ 3 คำสั่งหลักในการ "ย้อนกลับ" การเปลี่ยนแปลง ได้แก่ `git checkout`, `git reset`, และ `git revert` อย่างละเอียดตามสถานการณ์ต่างๆ หากคุณเชี่ยวชาญคำสั่งเหล่านี้แล้ว ก็ไม่จำเป็นต้องกลัวการทำผิดพลาดอีกต่อไป!


3 คำสั่ง "ย้อนกลับ": จะใช้คำสั่งไหนเมื่อไหร่?

Git มีคำสั่งในการย้อนกลับการเปลี่ยนแปลงอยู่หลายคำสั่ง ซึ่งอาจทำให้ผู้เริ่มต้นสับสนได้ง่าย ก่อนอื่น เรามาทำความเข้าใจบทบาทและการใช้งานของแต่ละคำสั่งกันแบบง่ายๆ

ถ้าจะให้เห็นภาพ `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 คำสั่งสำหรับย้อนกลับการเปลี่ยนแปลงแบบง่ายๆ

หากคุณใช้ 3 คำสั่งนี้ได้อย่างคล่องแคล่ว ก็ไม่จำเป็นต้องกลัวการทำผิดพลาดใน Git อีกต่อไป ขอให้สนุกกับการเขียนโค้ดและคอมมิตอย่างสบายใจ!