LEVEL 4 · ระดับเทพ
กู้ของหาย & ซ่อมประวัติ
เมื่อเข้าใจแล้วว่า object ไม่หายไปง่าย ๆ (บทที่ 12) คุณจะกู้สถานการณ์ที่คนอื่นคิดว่าหมดหวังได้ บทนี้คือชุดทักษะกู้ภัย — และเส้นแบ่งว่าเมื่อไหร่การเขียนประวัติใหม่ถึงปลอดภัย
14.1 กู้ commit ที่นึกว่าหายแล้ว
เผลอ reset --hard หรือลบ branch ที่ยังไม่ merge? commit เหล่านั้นกลายเป็น dangling object — ไม่มีป้ายชี้ แต่ยังอยู่ใน objects/ วิธีกู้: หา SHA จาก reflog (ถ้า HEAD เคยแตะ) แล้วชี้ branch ใหม่กลับไป หรือใช้ git fsck --lost-found กวาดหา commit ที่ลอยอยู่ทั้งหมด
$ git fsck --lost-found
dangling commit 3b7d8c1...
$ git branch recovered 3b7d8c1 # ปักป้ายกลับ — งานกลับมา14.2 ลบไฟล์ลับออกจากทั้งประวัติ
เผลอ commit รหัสผ่านหรือไฟล์ใหญ่ไป การลบใน commit ใหม่ไม่พอ — มันยังฝังอยู่ในประวัติเก่าทุก commit ที่ผ่านมา ต้องเขียนประวัติใหม่ทั้งสายด้วย git filter-repo (เครื่องมือมาตรฐานปัจจุบัน แทน filter-branch ที่ช้าและพลาดง่าย) ที่จะลบไฟล์นั้นออกจากทุก commit
14.3 เมื่อไหร่เขียนประวัติใหม่ได้ เมื่อไหร่ห้าม
กฎเดียวที่ต้องจำ ครอบคลุมทั้ง rebase, reset, filter-repo, commit --amend:
| สถานการณ์ | เขียนประวัติใหม่ |
|---|---|
| commit ยังอยู่ในเครื่องคุณคนเดียว (ยังไม่ push) | ได้เลย — อิสระเต็มที่ |
| push ขึ้น branch ส่วนตัวที่ไม่มีใครใช้ร่วม | ได้ แต่ต้อง push --force-with-lease |
| commit อยู่บน main/branch ที่ทีมใช้ร่วม | ห้าม — ใช้ revert แทน |
--force-with-lease ปลอดภัยกว่า --force ตรงที่มันจะปฏิเสธถ้ามีคนอื่น push เพิ่มเข้ามาหลังคุณดึงล่าสุด — กันการทับงานเพื่อนโดยไม่รู้ตัว
✅ สรุปบทที่ 14 — commit ที่ "หาย" กู้ได้จาก
reflogหรือfsck --lost-foundแล้วปักป้ายกลับ · ลบไฟล์ลับทั้งประวัติด้วยfilter-repoแต่ถ้าเคยรั่วต้องเปลี่ยนรหัสเสมอ · เขียนประวัติใหม่ได้อิสระถ้ายังไม่แชร์, ใช้--force-with-leaseบน branch ส่วนตัว, ห้ามแตะประวัติที่ทีมใช้ร่วม — ใช้revertแทน