LEVEL 4 · ระดับเทพ
เครื่องมือทรงพลัง
เครื่องมือเฉพาะทางที่แก้ปัญหาซึ่งคำสั่งพื้นฐานทำได้ลำบาก รู้ไว้ว่ามีอยู่ วันที่เจอโจทย์ตรงจะนึกออก
13.1 worktree — หลายโฟลเดอร์ ประวัติเดียว
ปกติหนึ่ง repo เปิดได้ทีละ branch git worktree ให้คุณกาง branch หลายอันลงหลายโฟลเดอร์พร้อมกันโดยใช้ประวัติชุดเดียว — แก้ฟีเจอร์ที่โฟลเดอร์หนึ่ง ขณะตรวจ PR อีกโฟลเดอร์ ไม่ต้อง stash สลับไปมา:
$ git worktree add ../myapp-hotfix hotfix # กาง branch "hotfix" ที่มีอยู่แล้วลงโฟลเดอร์ใหม่
$ git worktree add -b fix/urgent ../myapp-fix main # หรือสร้าง branch ใหม่จาก main พร้อมกางในตัว
$ git worktree list
/path/myapp 9f2c1a8 [main]
/path/myapp-hotfix 3b7d8c1 [hotfix]
$ git worktree remove ../myapp-hotfix # เลิกใช้แล้วเก็บโฟลเดอร์ทิ้งทั้งสองโฟลเดอร์ชี้ไปที่ .git ชุดเดียวกัน — commit จาก worktree ไหนก็เห็นได้จากอีกอันทันที ต่างจากการ clone ซ้ำที่ได้ประวัติแยกกันคนละชุด
13.2 hooks — สั่งให้ Git ทำงานอัตโนมัติ
ในทุก repo มีโฟลเดอร์ .git/hooks/ สำหรับสคริปต์ที่ Git เรียกอัตโนมัติเมื่อเกิดเหตุการณ์ ที่นิยมคือ pre-commit — รันก่อน commit ทุกครั้ง ใช้ตรวจ lint หรือฟอร์แมตโค้ดให้ผ่านก่อนถึงจะ commit ได้ ป้องกันงานเสียเข้าประวัติตั้งแต่ต้นทาง:
# .git/hooks/pre-commit — ตั้งชื่อไฟล์ให้ตรงเป๊ะ ไม่มีนามสกุล แล้ว chmod +x ให้รันได้
#!/bin/sh
npm run lint || { echo "lint ไม่ผ่าน — commit ถูกยกเลิก"; exit 1; }ถ้าสคริปต์จบด้วย exit code ที่ไม่ใช่ 0 Git จะยกเลิก commit ทันที — ยังไม่ทันขอข้อความ commit ด้วยซ้ำ hook ยอดนิยมอื่น ๆ: commit-msg (ตรวจรูปแบบข้อความ commit), pre-push (รันเทสต์ก่อนส่งขึ้น remote) หมายเหตุ: hook อยู่เฉพาะเครื่อง ไม่ถูก push ไปกับ repo — ถ้าอยากให้ทั้งทีมใช้ชุดเดียวกัน ตั้งค่า core.hooksPath ให้ชี้ไปโฟลเดอร์ที่ commit เก็บไว้ในโปรเจกต์แทน
13.3 submodule กับ subtree — ฝัง repo ในอีก repo
| Submodule | Subtree | |
|---|---|---|
| เก็บอะไร | แค่ตัวชี้ไป commit ของ repo อื่น | ก๊อปโค้ดเข้ามารวมในประวัติเลย |
| ข้อดี | repo หลักเล็ก แยกเวอร์ชันชัด | clone ทีเดียวได้ครบ ไม่ต้องสั่งเพิ่ม |
| ข้อเสีย | คนในทีมต้องรู้จักคำสั่ง submodule | ประวัติปนกัน อัปเดตย้อนกลับยุ่ง |
13.4 rerere & sparse-checkout
- rerere (reuse recorded resolution) — เปิดไว้แล้ว Git จะจำวิธีที่คุณแก้ conflict หนึ่ง ๆ พอเจอ conflict เดิมซ้ำ (เช่นตอน rebase ยาว ๆ) มันแก้ให้เองอัตโนมัติ
- sparse-checkout — กางเฉพาะบางโฟลเดอร์ของ repo ลงเครื่อง มีประโยชน์มากกับ monorepo ขนาดมหึมาที่คุณสนใจแค่ส่วนเดียว
✅ สรุปบทที่ 13 —
worktreeกาง branch หลายอันหลายโฟลเดอร์พร้อมกัน ·hooks(เช่น pre-commit) รันสคริปต์อัตโนมัติตามเหตุการณ์ · submodule = ตัวชี้ repo อื่น, subtree = ฝังโค้ดเข้ามาเลย · rerere จำวิธีแก้ conflict ซ้ำ, sparse-checkout กางเฉพาะบางส่วนของ repo ใหญ่