แม้คุณอาจไม่เจอปัญหา detached HEAD แต่ควรรู้เพื่อป้องกัน และรู้วิธีแก้หากเกิดขึ้น แนะนำ: อย่า commit บน detached HEAD แต่หากทำแล้ว จะแสดงวิธี save commits
การเตือนใจ (A Reminder)
เพื่อเข้าใจ HEAD คืออะไร มาทบทวนโครงสร้างต้นไม้ (tree-like) ของ Git:
- Working Directory (Working tree): ไดเรกทอรี local ของคุณ
git statusแสดงสถานะ working directory - HEAD: คือ snapshot ของ commit ล่าสุดของ branch ปัจจุบัน หากสลับ branch ด้วย
git checkoutHEAD จะเปลี่ยนไป commit ล่าสุดของ branch ใหม่ - Index (Staging area): เมื่อ
git addไฟล์เพื่อ commit จะเพิ่มเข้า index นี้
การเข้าใจ Attached HEAD
HEAD คือ commit ล่าสุดของ branch ที่คุณอยู่ git status จะบอก branch เช่น On branch master git log แสดงประวัติ commit พร้อม info:
commit 38373004b8f651b58cea64cd629e1e2c18c164a0 (HEAD -> master, origin/master, origin/HEAD) Author: Felipe <email> Date: Wed Sep 29 22:57:59 2020 -0500
หากเปลี่ยน branch ไป development ด้วย git checkout development HEAD จะย้ายไป commit ล่าสุดของ development branch ในกรณีปกติ HEAD ตามเราไปเรื่อยๆ เพราะ attached กับ commit ล่าสุดของ branch ที่อยู่
Detaching the HEAD
มีหลายวิธี detach HEAD:
- ใช้คำสั่ง
git checkout --detach - Checkout ไป commit hash โดยตรง เช่น
git checkout 38373004b8f651b58cea64cd629e1e2c18c164a0 - เพิ่ม
^0หลัง branch name เช่นgit checkout master^0
ไม่แน่ใจว่าคุณจะ detach HEAD ขอใจ แต่กรณีส่วนใหญ่เกิดจากผิดพลาด: อยาก checkout branch แต่ใช้ commit hash แทน branch name
หลัง detached HEAD อาจได้ warning:
$ git checkout 38373004b8f651b58cea64cd629e1e2c18c164a0 Note: checking out '38373004b8f651b58cea64cd629e1e2c18c164a0'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout.
บน detached HEAD หาก git status แม้ทำการเปลี่ยนแปลง จะแสดง:
HEAD detached at ac63806 nothing to commit, working tree clean
เหมือนเวลาหยุดนิ่ง ทุกอย่างที่ทำLost หรือไม่ไปไหน เพราะ HEAD ไชี้ไม่ไปที่ไหน บางคนใช้สำหรับ explore สถานะ repo เก่าโดยไม่กังวลแตกสิ่ง
Re-Attaching the HEAD
ต้องเข้าใจว่า branches ของคุณจะไม่ได้รับผลกระทบ หากคุณอยู่ใน detached state วิธีดีที่สุด reattach HEAD คือสร้าง branch ใหม่:
git checkout -b <branch-name>
หากไม่รู้ว่าอยู่ detached HEAD และทำการเปลี่ยนแปลงแล้ว ต้องสร้าง temporary branch และ merge เข้า branch ที่ต้องการ commit เช่น:
git checkout -b temp-branch git checkout master git merge temp-branch
คำสั่งนี้ commit การเปลี่ยนแปลงจาก temp-branch เข้า branch ที่ต้องการ (master)
สรุป
วันนี้เรียนรู้การ detach HEAD (ไม่ใช่จริงๆ) และทำอะไรหลังจากนั้น การเข้าใจ HEAD ในกลไก Git ช่วยเข้าใจกรณีพิเศษอย่าง detached HEAD
เรียนรู้ว่าไม่ต้องหวาดกลัวหากเจอ detached HEAD state เพียงจำไว้ว่า HEAD หลุด การเปลี่ยนแปลงและ commits จะไม่สะท้อนที่ไหน ให้ reattach HEAD ให้ถูกต้อง