ผมอยากได้หน้าต่าง branch ของ PHPStorm กลับมาใน terminal
ในโพสต์ก่อน ผมเล่าว่าย้ายงาน git จากปุ่มใน PHPStorm มาใช้คำสั่งใน terminal แทน คำสั่งพวกนั้นใช้ดีอยู่แล้ว แต่มีอย่างหนึ่งที่ยังคิดถึง คือกด Cmd+G Cmd+B แล้วมีหน้าต่าง branch ขึ้นมา พิมพ์ชื่อสองสามตัวแล้วเลือก Checkout ได้ทันที ใน terminal เราต้องจำชื่อ branch ให้ครบ หรือสั่ง git branch ดูก่อนแล้วค่อยพิมพ์ตาม
เลยทำ g ขึ้นมา หน้าตาและชื่อเมนูเลียนแบบหน้าต่าง branch ของ PHPStorm ใครเคยใช้ PHPStorm น่าจะคุ้นมือตั้งแต่ครั้งแรก

พิมพ์ g ใน repo ไหนก็ได้ branch หลักอยู่บนสุด ตามด้วย branch อื่นเรียงจากที่มี commit ล่าสุด
ติดตั้งครั้งเดียว ใช้ได้ทุก repo
git-prompt ไม่ได้ลงในแอป Laravel แต่เป็นโปรแกรม command line ที่ติดตั้งไว้ในเครื่องผ่าน composer global จึงใช้ได้กับทุก repo ทั้งโปรเจกต์ Laravel โปรเจกต์ frontend หรืออะไรก็ได้ที่เป็น git ตอนแรกผมคิดจะทำเป็นคำสั่ง artisan แต่แบบนั้นต้อง composer require ในทุกโปรเจกต์ แต่ละโปรเจกต์ก็ล็อกเวอร์ชันไว้ไม่เท่ากัน พอแก้คำสั่งทีก็ต้องไล่อัปเดตทีละที่
composer global require phattarachai/git-prompt
แล้วเพิ่ม alias ไว้ใน ~/.zshrc หรือจะใส่ ~/.composer/vendor/bin ไว้ใน PATH เลยก็ได้
alias g="$HOME/.composer/vendor/bin/g"
ต้องมี PHP 8.3 ขึ้นไป หน้าจอทั้งหมดสร้างด้วย Laravel Prompts ซึ่งใช้นอกแอป Laravel ได้ ส่วนงาน git ทั้งหมดเรียกคำสั่ง git ในเครื่องตรง ๆ ไม่มี library ไหนมาทำแทน
พิมพ์แค่บางส่วนของชื่อ branch แล้วกด Enter
แท็บแรกคือ Branches พิมพ์อะไรลงไปก็กรองทันทีแบบเดียวกับใน IDE พิมพ์ de ก็เจอ develop หรือพิมพ์ตัวอักษรตามลำดับอย่าง vr ก็เจอ hotfix/vat-rounding ชื่อที่ขึ้นต้นด้วยคำที่พิมพ์จะขึ้นก่อน และแถวแรกที่ตรงเลือกไว้ให้แล้ว กด Enter ได้เลยไม่ต้องกดลูกศรลงมาก่อน
สัญลักษณ์หน้าแต่ละแถวมีความหมายแบบนี้
●branch ที่อยู่ตอนนี้★branch หลักที่เราตั้งไว้ (ดูหัวข้อถัดไป)↑1มี commit ที่ยังไม่ได้ push และ↓2มี commit บน remote ที่ยังไม่ได้ดึงลงมาworktreebranch นี้เปิดอยู่ในอีกโฟลเดอร์ผ่านgit worktreeorigin/…branch ที่มีแค่บน remote พอเลือก Checkoutgจะสร้าง branch ในเครื่องที่ track ตัวบน remote ให้
ตั้ง branch หลักให้อยู่บนสุด
ค่าเริ่มต้นคือ main, master และ develop ถ้าโปรเจกต์มี branch ตาม environment อย่าง uat ก็ตั้งเองได้ ลำดับที่ใส่คือลำดับที่แสดง
git config --global gitprompt.protected "develop uat main"
repo ไหนใช้ชื่อต่างออกไป ตั้งค่าใน repo นั้นโดยไม่ต้องใส่ --global ค่าของ repo จะใช้แทนค่า global ทั้งชุด ส่วน branch ที่เหลือเรียงตาม commit ล่าสุด ถ้าอยากให้ feat/, fix/, hotfix/ อยู่เป็นกลุ่ม เลือก Sort branches by name ในแท็บ Actions แล้ว g จะจำไว้ใช้ครั้งต่อไป
เมนูของแต่ละ branch ใช้ชื่อเดียวกับใน PHPStorm
กด Enter ที่ branch ไหนจะได้เมนูของ branch นั้น เมนูนี้ก็กรองได้เหมือนกัน พิมพ์ d แล้วกด Enter ก็คือ Delete ถ้ากดผิดหน้า กด Esc ย้อนกลับไปหน้าก่อนได้

เมนูย่อยทุกหน้าพิมพ์กรองได้ คำที่ขึ้นต้นด้วยตัวที่พิมพ์ขึ้นก่อน
แต่ละเมนูตรงกับคำสั่ง git แบบนี้ สมมติว่าอยู่ที่ develop แล้วเลือก feat/export-pdf
| เมนู | คำสั่งที่ g รัน |
|---|---|
| Checkout | git switch feat/export-pdf |
| Checkout and Update | git switch แล้วอัปเดตแบบ Update Project |
| Checkout and Rebase onto 'develop' | git switch feat/export-pdf แล้ว git rebase --autostash develop |
| Compare with 'develop' | git log develop..feat/export-pdf และกลับกัน |
| Merge into 'develop' | git merge --no-edit --autostash feat/export-pdf |
| Rebase 'develop' onto | git rebase --autostash feat/export-pdf |
| New Branch from | git switch --no-track -c <ชื่อใหม่> feat/export-pdf |
| Rename | git branch --move |
| Delete | git branch --delete แล้วถามว่าจะลบบน remote ด้วยไหม |
ทุกคำสั่งที่รันขึ้นให้เห็นก่อน
g ไม่ได้ซ่อน git ไว้ข้างหลัง ก่อนรันทุกคำสั่งจะพิมพ์บรรทัด → git … ออกมาก่อน ตามด้วยผลจาก git ใช้ไปเรื่อย ๆ ก็จำคำสั่งได้เอง และพอมีอะไรแปลก ๆ ก็ตามได้ว่าเกิดจากคำสั่งไหน

Checkout and Update ที่ develop สลับ branch แล้วดึงงานล่าสุดลงมา
แท็บ Actions รวมงานที่ไม่ผูกกับ branch ไหน
กด Tab เพื่อสลับแท็บ หรือกด ← → ตอนช่องค้นหายังว่าง ข้อความที่พิมพ์ไว้ตามไปด้วย พิมพ์ st แล้วกด Tab ก็เจอ Status กับ Stash เลย

แท็บ Actions ระหว่าง merge หรือ rebase ค้าง จะมี Continue กับ Abort อยู่บนสุด
- Update Project สั่ง
git fetch --pruneแล้วอัปเดต branch ที่อยู่ ถ้ามีแค่ของใหม่จาก remote จะ fast-forward ไปเลย แต่ถ้าเราเองก็มี commit ใหม่ด้วย จะถามก่อนว่าจะ rebase หรือ merge ส่วนงานที่ยังไม่ commit ใช้--autostashเก็บไว้แล้วคืนให้หลังอัปเดต ถ้าเลือกแบบเดิมทุกครั้ง ตั้งค่าเริ่มต้นได้ด้วยgit config --global gitprompt.update rebase - Commit… เลือกไฟล์ด้วย Space ใส่ข้อความ แล้วถามว่าจะ push ต่อเลยไหม ถ้า stage ไฟล์ไว้บางส่วนแล้ว จะติ๊กไว้ให้เฉพาะไฟล์ชุดนั้น
- Push… branch ใหม่ใส่
--set-upstreamให้ ถ้า push ไม่ผ่านเพราะบน remote มี commit ที่เรายังไม่มี จะให้เลือกว่าจะ Update ก่อนแล้วค่อย push หรือ push ทับด้วย--force-with-lease - Stash… เก็บงานค้างรวมไฟล์ใหม่ หรือเลือก stash เก่ามา pop, apply, ดูไฟล์ หรือลบทิ้ง
- Status ตารางไฟล์ที่เปลี่ยน พร้อมบอกว่าไฟล์ไหน stage แล้ว
git pull เฉย ๆ ก็ดึงงานลงมาได้เหมือนกัน แต่พอ branch แยกทางกัน git จะทำตาม config ที่ตั้งไว้ หรือหยุดถ้ายังไม่ได้ตั้ง Update Project เลือกถามเราก่อน รายละเอียดเรื่อง fetch กับ pull อยู่ในโพสต์คำสั่ง git ที่ใช้ทุกวัน
branch หลักต้องพิมพ์ชื่อยืนยันก่อนทุกครั้ง
ส่วนที่ผมใส่ใจที่สุดคือกันไม่ให้พลาดกับ branch ที่หลายคนใช้ร่วมกัน
- merge, push, rebase หรือลบ branch ที่อยู่ใน
gitprompt.protectedต้องพิมพ์ชื่อ branch ยืนยันก่อน กด Enter ผ่านไปเฉย ๆ ไม่ได้ - ไม่มี
--forceเฉย ๆ เลย force push ใช้--force-with-leaseซึ่งจะไม่ยอมทับ ถ้าบน remote มีงานของคนอื่นที่เรายังไม่ได้ดึงลงมา - Checkout ตอนที่งานค้างชนกับ branch ปลายทาง จะเสนอ Smart checkout ให้ เก็บงานไว้ใน stash สลับ branch แล้วเอางานกลับมาให้ เหมือนใน PHPStorm
- branch ที่เปิดอยู่ใน worktree อื่น
gจะบอกว่าอยู่โฟลเดอร์ไหน แทนที่จะปล่อยให้ git error - merge หรือ rebase แล้วเจอ conflict จะหยุดให้เลือกว่าจะ Abort กลับไปเหมือนเดิม หรือไปแก้ใน editor ก่อน แก้เสร็จพิมพ์
gอีกที แล้วเลือก Continue ซึ่งจะเช็คก่อนว่าไม่มีเครื่องหมาย<<<<<<<เหลืออยู่ ถึงจะ stage แล้วไปต่อ
ลบ branch เก่าทีละหลายตัว ทั้งในเครื่องและบน remote
ทำงานไปสักพัก branch ที่ merge แล้วก็ค้างอยู่เต็มไปหมด ทั้งในเครื่องและบน GitHub เลือก Delete Branches ในแท็บ Actions หรือสั่ง g d ตรง ๆ

พิมพ์ merged แล้วกด Ctrl+A ติ๊กทุกแถวที่ตรงในครั้งเดียว
gสั่งgit fetch --pruneก่อน รายการจะได้ตรงกับบน remote- แต่ละแถวมีป้ายบอก
mergedคือรวมเข้า branch หลักของ remote แล้วgoneคือตัวบน remote ลบไปแล้ว เช่นหลัง merge PR ส่วนlocal onlyกับremote onlyบอกว่ามีอยู่ฝั่งเดียว เรียง branch เก่าสุดไว้บนสุด - กด Space ติ๊กทีละแถว หรือพิมพ์
mergedหรือgoneแล้วกด Ctrl+A ติ๊กทุกแถวที่ตรง - เลือกว่าจะลบในเครื่องอย่างเดียว หรือลบบน remote ด้วย แล้ว
gจะแสดงรายการทั้งหมดให้ยืนยันอีกที - branch ที่ยังมี commit ไม่ได้ merge ไปไหน จะเตือนแยกและไม่ลบให้ จนกว่าเราจะยืนยันอีกรอบ
- branch หลัก branch ที่อยู่ตอนนี้ และ branch ที่เปิดใน worktree อื่น ไม่ขึ้นมาในรายการเลย
คำสั่งลัด
พิมพ์ g เฉย ๆ ได้หน้าค้นหาครบทุกอย่าง ถ้ารู้อยู่แล้วว่าจะทำอะไร ใส่คำสั่งย่อยต่อท้ายได้
| คำสั่ง | ทำอะไร |
|---|---|
g |
หน้าค้นหา แท็บ Branches และ Actions |
g b |
เฉพาะ branch |
g s |
Status |
g up |
Update Project |
g c |
Commit |
g p |
Push |
g st |
Stash |
g n |
New branch จาก branch ที่อยู่ |
g d |
ลบ branch ทีละหลายตัว |
ทุกหน้าใช้ปุ่มชุดเดียวกัน พิมพ์เพื่อกรอง Enter เลือก Tab สลับแท็บ Esc ย้อนกลับ และ Ctrl+C ออกทันที
GitHub: phattarachai/git-prompt






