ข้ามไปยังเนื้อหาหลัก
ProgrammerThailand

AI & Vibe Coding

Git Workflow เมื่อทำงานกับ AI: Commit เล็ก ย้อนกลับง่าย

Git Workflow เมื่อทำงานกับ AI: Commit เล็ก ย้อนกลับง่าย

เวลาทำงานกับ AI ผู้ช่วยเขียนโค้ด สิ่งที่เปลี่ยนไปคือความเร็ว ในไม่กี่วินาที AI อาจแก้ไฟล์ไปสิบไฟล์ บางครั้งได้ผลดี บางครั้งพาโค้ดที่เคยทำงานได้พังไปทั้งแถบ ถ้าไม่มี Git เป็นตาข่ายรองรับ เราจะไม่รู้ว่าอะไรเปลี่ยนไปบ้าง และย้อนกลับไปจุดที่ดีล่าสุดไม่ได้ บทความนี้จะเสนอ workflow ที่ใช้ได้จริง ตั้งแต่การแยก branch ต่อเรื่อง commit ทุกครั้งที่ผ่านแต่ละขั้น ตรวจ git diff ก่อนรับงาน ใช้ stash และ reset อย่างปลอดภัย ไปจนถึงการเขียน commit message ที่อ่านแล้วเข้าใจ

หลักคิด: ให้ Git เป็นปุ่ม Undo ที่เชื่อถือได้

ปุ่ม undo ใน editor หรือฟีเจอร์ย้อนกลับในเครื่องมือ AI บางตัวช่วยได้ระดับหนึ่ง แต่ไม่ครอบคลุมทุกกรณี เช่น เมื่อ AI รันคำสั่งใน terminal สร้างไฟล์ใหม่ หรือแก้ไฟล์ข้ามหลายรอบสนทนา Git จึงเป็นเครื่องมือหลักที่ควรพึ่ง หลักง่าย ๆ มีสามข้อ:

  1. เริ่มจาก working tree ที่สะอาด ก่อนให้ AI ทำงาน ให้ git status แล้วต้องไม่มีงานค้างที่ยังไม่ commit ไม่อย่างนั้นจะแยกไม่ออกว่าอะไรเป็นงานของเรา อะไรเป็นงานของ AI
  2. หนึ่งขั้นที่ผ่าน = หนึ่ง commit ทุกครั้งที่ได้ผลลัพธ์ที่ทดสอบแล้วใช้ได้ ให้ commit ทันที
  3. ไม่รับโค้ดที่ยังไม่ได้อ่าน diff ไม่ว่า AI จะอธิบายมาสวยแค่ไหน

แยก branch ต่อเรื่อง

ทุกงานควรมี branch ของตัวเอง ทำให้ทดลองได้เต็มที่ ถ้าแนวทางไม่เวิร์กก็ทิ้งทั้ง branch ได้โดยไม่กระทบ main

# อัปเดต main ให้ล่าสุดก่อน
git switch main
git pull

# สร้าง branch ใหม่สำหรับงานนี้
git switch -c feature/export-orders-csv

# ตรวจว่าไม่มีงานค้าง
git status

ถ้าต้องการลองให้ AI ทำสองแนวทางเพื่อเปรียบเทียบ ก็แตก branch แยกเป็นสองสาย เช่น try/export-with-stream กับ try/export-with-batch แล้วเลือกสายที่ดีกว่ามา merge ส่วนอีกสายลบทิ้ง อีกทางเลือกที่สะดวกเมื่อต้องรันสองงานพร้อมกันคือ git worktree add ../export-alt -b try/export-alt ซึ่งสร้างโฟลเดอร์ทำงานแยก ใช้ repository เดียวกัน

ตั้งชื่อ branch ให้บอกเรื่อง ไม่ใช่บอกเครื่องมือ เช่น fix/login-redirect-loop ดีกว่า ai-changes-2

Commit ทุกขั้นที่ผ่าน

ให้แบ่งงานใหญ่เป็นขั้นเล็ก ๆ แล้วสั่ง AI ทีละขั้น เมื่อแต่ละขั้นผ่านการทดสอบ ให้ commit ก่อนเริ่มขั้นถัดไป ตัวอย่างการแบ่งงาน "เพิ่มปุ่ม export คำสั่งซื้อเป็น CSV":

  1. เพิ่ม method ใน service ที่ดึงข้อมูลคำสั่งซื้อตามช่วงวันที่ พร้อม unit test แล้ว commit
  2. เพิ่ม action ใน controller ที่ส่งไฟล์ CSV ออกไป แล้ว commit
  3. เพิ่มปุ่มในหน้า view และตรวจสิทธิ์ผู้ใช้ แล้ว commit

ถ้าขั้นที่ 3 พัง เราย้อนกลับไปจุดหลังขั้นที่ 2 ได้ทันที โดยไม่เสียงานที่ดีอยู่แล้ว

# รันเทสต์ก่อน commit ทุกครั้ง
vendor/bin/codecept run unit

# เลือก stage เฉพาะส่วนที่ต้องการ ทีละ hunk
git add -p

git commit -m "feat(order): add OrderExportService::findByDateRange"

git add -p มีประโยชน์มากเวลาทำงานกับ AI เพราะบ่อยครั้ง AI แถมการเปลี่ยนแปลงที่เราไม่ได้ขอ เช่น จัด format ไฟล์ใหม่ทั้งไฟล์ หรือเปลี่ยนชื่อตัวแปรที่ไม่เกี่ยวข้อง เราเลือก stage เฉพาะส่วนที่ตั้งใจได้ ส่วนที่เหลือค่อยทิ้งไป

อ่าน git diff ก่อนรับทุกครั้ง

นี่คือขั้นที่สำคัญที่สุดและถูกข้ามบ่อยที่สุด ก่อน commit ให้ดูว่า AI แก้อะไรไปบ้าง

# ภาพรวมว่าไฟล์ไหนเปลี่ยน กี่บรรทัด
git diff --stat

# รายละเอียดของส่วนที่ยังไม่ stage
git diff

# รายละเอียดของส่วนที่ stage แล้ว ซึ่งกำลังจะ commit
git diff --staged

# ไฟล์ใหม่ที่ยังไม่ถูก track จะไม่โผล่ใน git diff ต้องดูจาก status
git status --short

สิ่งที่ควรมองหาขณะอ่าน diff:

  • ไฟล์ที่ไม่ควรถูกแตะ เช่น .env, ไฟล์ config ของ production, composer.lock ที่เปลี่ยนโดยไม่ได้ตั้งใจ
  • เทสต์ที่ถูกลบ ถูก skip หรือถูกแก้ค่าที่คาดหวังให้ผ่าน ซึ่งเป็นสัญญาณอันตราย
  • secret หรือ token ที่หลุดเข้ามาในโค้ด
  • การเปลี่ยนแปลงขนาดใหญ่ที่ไม่เกี่ยวกับงาน เช่น จัด format ทั้งไฟล์ ซึ่งทำให้ review ยาก
  • SQL ที่ต่อ string แทนการใช้ parameter binding และ output ที่ไม่ผ่าน Html::encode()

ถ้า diff ยาวจนอ่านไม่ไหว นั่นคือสัญญาณว่าขั้นนั้นใหญ่เกินไป ให้ย้อนกลับแล้วสั่ง AI ใหม่ให้เล็กลง

Stash และ Reset: ย้อนกลับอย่างปลอดภัย

เมื่อผลลัพธ์ไม่ตรงใจ มีหลายวิธีย้อนกลับ ขึ้นกับว่าอยากเก็บงานไว้ดูหรือไม่

สถานการณ์คำสั่ง
อยากเก็บงานไว้ก่อน เผื่อกลับมาดูgit stash push -u -m "ai attempt 1"
ดูรายการที่ stash ไว้git stash list
นำงานที่ stash กลับมาgit stash pop หรือ git stash apply stash@{0}
ทิ้งการแก้ไขของไฟล์เดียวgit restore path/to/File.php
ทิ้งการแก้ไขทั้งหมดที่ยังไม่ commitgit reset --hard
ลบไฟล์ใหม่ที่ไม่ถูก track (ดูก่อน)git clean -n แล้วค่อย git clean -fd
ยกเลิก commit ล่าสุดแต่เก็บการแก้ไขไว้git reset --soft HEAD~1
ย้อน commit ที่ push ไปแล้วgit revert <commit>

ข้อควรระวัง:

  • git reset --hard และ git clean -fd ลบงานที่ยังไม่ commit ทิ้งถาวร ถ้าไม่แน่ใจให้ใช้ git stash push -u แทน ซึ่งเก็บไว้ให้กู้คืนได้
  • อย่าใช้ reset กับ commit ที่ push ขึ้น remote ที่คนอื่นใช้ร่วมแล้ว ให้ใช้ git revert ซึ่งสร้าง commit ใหม่ที่กลับค่าการเปลี่ยนแปลง
  • ถ้าเผลอ reset ไปแล้ว git reflog ช่วยหา commit ที่หายไปกลับมาได้ ตราบใดที่งานนั้นเคยถูก commit
  • อย่าอนุญาตให้ AI agent รันคำสั่งอย่าง reset --hard, clean -fd หรือ push --force เองโดยไม่ถามก่อน

เขียน commit message ที่อ่านแล้วเข้าใจ

AI เขียน commit message ให้ได้ดีพอสมควรถ้าเราให้มันอ่าน diff ที่ stage แล้ว แต่ต้องตรวจเสมอว่าตรงกับสิ่งที่เปลี่ยนจริง รูปแบบที่หลายทีมใช้คือ Conventional Commits: บรรทัดแรกเป็น type(scope): สรุปสั้น ๆ เว้นหนึ่งบรรทัด แล้วตามด้วยรายละเอียดว่าทำไมถึงเปลี่ยน

ไม่ดี:
update code
fix bug
AI changes

ดี:
fix(auth): prevent redirect loop when session expires

The login action redirected to returnUrl even when returnUrl
pointed back to /site/login. Fall back to the home page instead.
Add a unit test covering the expired-session case.

Prompt สำหรับให้ AI ร่าง commit message:

นี่คือผลของ git diff --staged
เขียน commit message ตาม Conventional Commits
- บรรทัดแรกไม่เกิน 72 ตัวอักษร ใช้ภาษาอังกฤษ
- body อธิบายว่า "ทำไม" ไม่ใช่แค่ "ทำอะไร"
- ห้ามกล่าวถึงสิ่งที่ไม่มีใน diff

บางทีมเพิ่ม trailer ระบุว่าใช้ AI ช่วยในการเขียน เพื่อความโปร่งใส ให้ตกลงเป็นนโยบายร่วมกันในทีม

สรุป

  • เริ่มทุกงานจาก working tree ที่สะอาดและ branch แยกต่อเรื่อง เพื่อทดลองได้โดยไม่กระทบ main
  • แบ่งงานเป็นขั้นเล็ก รันเทสต์ แล้ว commit ทุกครั้งที่ผ่าน เพื่อให้ย้อนกลับไปจุดที่ดีได้เสมอ
  • อ่าน git diff และ git status ก่อนรับงานของ AI ทุกครั้ง และใช้ git add -p คัดเฉพาะส่วนที่ตั้งใจ
  • ใช้ stash เมื่อไม่แน่ใจ ใช้ reset --hard เฉพาะเมื่อแน่ใจ และใช้ revert กับสิ่งที่ push ไปแล้ว
  • commit message ที่ดีอธิบายว่าทำไม ให้ AI ร่างได้แต่คนต้องตรวจ

ลองทำ

สร้าง repository ทดลอง แล้วทำ workflow นี้ครบหนึ่งรอบ: สร้าง branch feature/slugify-helper ให้ AI เขียนฟังก์ชันแปลงข้อความเป็น slug พร้อมเทสต์ แล้ว commit จากนั้นสั่ง AI ให้ "ปรับปรุง" ฟังก์ชันอีกรอบ อ่าน git diff ถ้าพบการเปลี่ยนแปลงที่ไม่ต้องการ ให้ลอง git stash push -u -m "attempt 2" แล้วสั่งใหม่ด้วย prompt ที่แคบลง สุดท้ายให้ AI ร่าง commit message จาก git diff --staged แล้วแก้ให้ถูกต้องก่อน commit

ติดปัญหาตอนทำตาม? ถามในชุมชน

ความคิดเห็น (0)

ยังไม่มีความคิดเห็น — เริ่มคุยเป็นคนแรก ถามสิ่งที่สงสัย หรือแชร์ประสบการณ์ของคุณ