Developer Tools

คู่มือ Git Workflow: การแตก Branch, การ Merge และการทำงานร่วมกันเป็นทีม

เรียนรู้กลยุทธ์การแตก Branch ใน Git, แนวปฏิบัติด้าน Commit, การใช้ Rebase เทียบกับ Merge และ Workflow ที่ทีมวิศวกรมืออาชีพใช้งานจริง

8 นาทีในการอ่าน

Developer looking at code on a screen

Git คือรากฐานของ Workflow ในทุกทีมพัฒนาซอฟต์แวร์ยุคใหม่ แต่นักพัฒนาหลายคนใช้แค่ commit, push, และ pull เท่านั้น โดยทิ้งฟีเจอร์ที่ช่วยให้การทำงานร่วมกันราบรื่นและลดความขัดแย้งไว้เฉย ๆ คู่มือนี้ครอบคลุมกลยุทธ์การแตก Branch, แนวปฏิบัติด้าน Commit และคำสั่งที่ทีมมืออาชีพใช้ในชีวิตประจำวัน

แนวคิดหลักที่ต้องเข้าใจ

Git คือ directed acyclic graph ของ Snapshot (Commit) แต่ละ Commit ชี้ไปยัง Parent ของมัน Branch คือตัวชี้ (Pointer) ที่ตั้งชื่อไว้ — สร้างได้ง่าย รวดเร็ว และแทบไม่มีต้นทุน

main:    A → B → C → D
feature:         C → E → F

การแตก Branch ไม่ได้คัดลอกไฟล์ — แค่สร้าง Pointer ใหม่เท่านั้น นั่นคือเหตุผลที่การสร้าง Branch ใช้เวลาแค่มิลลิวินาที ไม่ว่า Repository จะใหญ่แค่ไหน

กลยุทธ์การแตก Branch

GitHub Flow (เรียบง่าย เหมาะกับ Continuous Delivery)

เหมาะสำหรับทีมที่ Deploy บ่อยครั้ง:

  1. main ต้องพร้อม Deploy ได้เสมอ
  2. สร้าง Feature Branch สำหรับทุกการเปลี่ยนแปลง
  3. เปิด Pull Request เมื่อพร้อมให้ตรวจสอบ
  4. Merge เข้า main หลังได้รับการอนุมัติ
  5. Deploy ทันที
git checkout -b feature/add-user-auth
# ... make changes ...
git push origin feature/add-user-auth
# Open PR → review → merge → deploy

Git Flow (สำหรับการ Release ที่มีโครงสร้างชัดเจน)

เหมาะสำหรับผลิตภัณฑ์ที่มีการ Release เป็นเวอร์ชัน (แอปพลิเคชัน, ไลบรารี):

  • main — Code สำหรับ Production เท่านั้น
  • develop — Branch สำหรับรวม Code
  • feature/* — ฟีเจอร์ใหม่ (แตกจาก develop)
  • release/* — เตรียมการ Release (แตกจาก develop)
  • hotfix/* — แก้ไขด่วนใน Production (แตกจาก main)

มีโครงสร้างที่ชัดเจนแต่ซับซ้อนกว่า ควรใช้ GitHub Flow ก่อน เว้นแต่คุณมีความจำเป็นจริง ๆ ในการจัดการ Release แบบขนาน

Trunk-Based Development

นักพัฒนา Commit ตรงไปที่ main (หรือ Branch อายุสั้นที่ใช้น้อยกว่า 1 วัน) ใช้ Feature Flag ควบคุมสิ่งที่ผู้ใช้เห็น ต้องการ CI/CD ที่แข็งแกร่งและ Test Coverage ที่ครอบคลุม ใช้โดย Google, Facebook และทีมที่ทำงานด้วยความเร็วสูง

การเขียน Commit Message ที่ดี

Commit Message คือจดหมายถึงตัวคุณในอนาคต (และเพื่อนร่วมทีม) ทำตามรูปแบบ Conventional Commits:

<type>(<scope>): <short summary>

<optional body — what and why, not how>

<optional footer — breaking changes, issue refs>

ประเภท (Types):

  • feat — ฟีเจอร์ใหม่
  • fix — แก้ไข Bug
  • docs — เอกสารเท่านั้น
  • refactor — เปลี่ยนแปลง Code ที่ไม่ใช่การแก้ Bug หรือเพิ่มฟีเจอร์
  • test — เพิ่มหรือแก้ไข Test
  • chore — กระบวนการ Build, Dependencies, Tooling

ตัวอย่าง:

feat(auth): add JWT refresh token rotation

Implements sliding session windows using refresh token rotation.
Previous tokens are invalidated on use to detect theft.

Closes #142
fix(api): return 404 instead of 500 for missing user

The /users/:id endpoint was throwing an unhandled exception when
the user didn't exist. Now returns a proper 404 with error message.

หลักง่าย ๆ: ถ้า Commit Message ของคุณคือ fix stuff หรือ WIP ทีมของคุณคงเกลียดคุณ ทำให้มันสื่อความหมายหน่อย

Merge เทียบกับ Rebase

Merge

git checkout main
git merge feature/my-feature

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

A → B → C → M (merge commit)
         ↑   ↑
         E → F (feature)

ใช้ Merge สำหรับ: รวม Branch ที่ใช้งานนาน, เก็บบริบทใน History

Rebase

git checkout feature/my-feature
git rebase main

นำ Commit ของคุณไปวางซ้ำบน Branch เป้าหมาย สร้าง Linear History — ดูเหมือนว่าฟีเจอร์ถูกสร้างบน main เวอร์ชันล่าสุด

Before: A → B → C (main)
                 ↑
            D → E (feature, based off B)

After:  A → B → C → D' → E' (feature rebased onto C)

ใช้ Rebase สำหรับ: ทำความสะอาด Commit ในเครื่องก่อนเปิด PR, อัปเดต Feature Branch ให้ทันสมัย

กฎสำคัญ: อย่า Rebase Commit ที่ Push ไปยัง Branch ที่ใช้ร่วมกันแล้ว Rebase เขียนทับ History — มันจะทำลาย Local Branch ของคนอื่น

Interactive Rebase: ทำความสะอาด History

ก่อนเปิด PR ให้ Squash และ Fixup Commit ที่ยุ่งเหยิงออก:

git rebase -i HEAD~4   # interactively edit the last 4 commits

ตัวเลือกใน Interactive Editor:

  • pick — เก็บ Commit ไว้
  • squash — รวมเข้ากับ Commit ก่อนหน้า, รวม Message
  • fixup — รวมเข้ากับ Commit ก่อนหน้า, ทิ้ง Message
  • reword — เก็บการเปลี่ยนแปลง, แก้ไข Message
  • drop — ลบ Commit ทิ้งทั้งหมด

การจัดการ Conflict

Conflict เกิดขึ้นเมื่อสอง Branch แก้ไขบรรทัดเดียวกัน Git จะทำเครื่องหมายไว้:

<<<<<<< HEAD (your branch)
const timeout = 5000;
=======
const timeout = 3000;
>>>>>>> feature/update-timeouts

แก้ไขโดยแก้ไขไฟล์ให้อยู่ในสถานะที่ถูกต้อง (ลบ Marker ออก) จากนั้น:

git add src/config.ts
git merge --continue   # or git rebase --continue

ป้องกันดีกว่าแก้ไข:

  • Pull จาก main บ่อย ๆ เพื่อให้ Branch มีอายุสั้น
  • สื่อสารกับเพื่อนร่วมทีมเมื่อทำงานในไฟล์เดียวกัน
  • ทำ PR ให้เล็ก — PR ขนาดใหญ่มี Conflict มากกว่าและ Review ยากกว่า

คำสั่งสำคัญที่ใช้ทุกวัน

# Start a new feature
git checkout -b feature/my-feature

# Stage specific changes (not the whole file)
git add -p

# View unstaged changes
git diff

# View staged changes
git diff --staged

# Amend the last commit (before pushing)
git commit --amend --no-edit

# Temporarily save uncommitted work
git stash
git stash pop

# Find which commit introduced a bug (binary search)
git bisect start
git bisect bad              # current commit is bad
git bisect good v1.2.0      # last known good commit

# Recover a deleted branch or lost commit
git reflog

# See a visual graph of branches
git log --oneline --graph --all

แนวปฏิบัติที่ดีสำหรับ Pull Request

PR ที่ดีควร:

  • ทำสิ่งเดียว — ผู้ Review เข้าใจการเปลี่ยนแปลงได้ครบถ้วน
  • มีคำอธิบายที่ชัดเจน — อะไรเปลี่ยน, ทำไม และวิธีทดสอบ
  • มีขนาดเล็ก — น้อยกว่า 400 บรรทัดของ Diff เป็นเป้าหมายคร่าว ๆ
  • ผ่าน CI — อย่าขอ Review บน Build ที่พัง
  • เชื่อมโยงกับ IssueCloses #42 ปิด Issue โดยอัตโนมัติเมื่อ Merge

ใช้ README Generator ของเราเพื่อสร้างโครงสร้างเอกสารควบคู่ไปกับการเปลี่ยนแปลง Code ของคุณ

สิ่งสำคัญที่ต้องรู้เกี่ยวกับ .gitignore

เพิ่มสิ่งเหล่านี้ใน .gitignore เสมอ:

# Environment variables
.env
.env.local
.env.*.local

# Dependencies
node_modules/
vendor/

# Build output
dist/
build/
.next/

# OS files
.DS_Store
Thumbs.db

# Editor files
.vscode/settings.json
.idea/
*.swp

สร้าง .gitignore เฉพาะโปรเจกต์ได้ที่ gitignore.io — รองรับภาษาและเครื่องมือหลายร้อยรายการ

ความเชี่ยวชาญใน Git สะสมขึ้นตามเวลา เรียนรู้แนวคิดหลัก นำแนวปฏิบัติด้าน Commit ที่ดีมาใช้ และการทำงานร่วมกันของทีมคุณจะราบรื่นขึ้นอย่างเห็นได้ชัด