Git เป็นเครื่องมือที่นักพัฒนาทุกคนต้องใช้ แต่ส่วนใหญ่ใช้แค่ add, commit, push ซึ่งเป็นเพียงแค่ส่วนเล็กๆ ของความสามารถทั้งหมดของ Git ในปี 2026 การทำงานเป็นทีมที่มีประสิทธิภาพต้องการความเข้าใจ Git ในระดับลึก ตั้งแต่ Branching Strategy ที่เหมาะกับขนาดทีม ไปจนถึง Interactive Rebase, Cherry-pick, Git Hooks และเทคนิคการกู้คืนข้อมูลที่สูญหาย
บทความนี้จะพาคุณไปเรียนรู้ Git ในระดับขั้นสูงที่ Senior Developer และ Tech Lead ต้องรู้ ครอบคลุมทุก Workflow ที่ใช้ในบริษัท Tech ชั้นนำ พร้อมตัวอย่างจากสถานการณ์จริงที่พบบ่อยในการทำงานเป็นทีม
Branching Strategies — เลือกให้เหมาะกับทีม
การเลือก Branching Strategy ที่เหมาะสมเป็นการตัดสินใจที่สำคัญมากสำหรับทีมพัฒนา ถ้าเลือกผิดจะทำให้เกิดปัญหา Merge Conflict บ่อย ขั้นตอนการ Deploy ซับซ้อน และทีมทำงานช้าลง มาดู Strategy หลักๆ ที่ใช้กันในปี 2026
1. Git Flow
Git Flow เป็น Branching Strategy ที่ Vincent Driessen คิดค้นขึ้นในปี 2010 เหมาะสำหรับซอฟต์แวร์ที่มี Release Cycle ชัดเจน เช่น Mobile App หรือ Desktop Software ที่ต้องออก Version ใหม่เป็นระยะ แต่อาจจะซับซ้อนเกินไปสำหรับ Web App ที่ Deploy บ่อย
# Git Flow มี 5 ประเภท Branch:
# 1. main (production) — โค้ดที่ Deploy แล้วเท่านั้น
# 2. develop — รวม Feature ทั้งหมดก่อน Release
# 3. feature/* — พัฒนาฟีเจอร์ใหม่
# 4. release/* — เตรียมออก Release
# 5. hotfix/* — แก้ Bug ด่วนใน Production
# ติดตั้ง git-flow extension
# Mac: brew install git-flow
# Linux: apt install git-flow
# เริ่มต้น
git flow init
# สร้าง Feature Branch
git flow feature start user-authentication
# ทำงาน... commit...
git flow feature finish user-authentication
# -> merge เข้า develop อัตโนมัติ
# สร้าง Release Branch
git flow release start 1.2.0
# แก้ Bug สุดท้าย... bump version...
git flow release finish 1.2.0
# -> merge เข้า main + develop + สร้าง tag
# สร้าง Hotfix Branch
git flow hotfix start fix-login-crash
# แก้ Bug ด่วน...
git flow hotfix finish fix-login-crash
# -> merge เข้า main + develop
2. GitHub Flow
GitHub Flow เป็น Strategy ที่เรียบง่ายที่สุด เหมาะสำหรับทีมที่ Deploy บ่อย (Continuous Deployment) มีแค่ main branch และ Feature branch ข้อดีคือเรียบง่าย ทุกคนเข้าใจได้ทันที ข้อเสียคือไม่รองรับ Multiple Versions
# GitHub Flow ขั้นตอน:
# 1. สร้าง Branch จาก main
git switch -c feature/new-dashboard
# 2. Commit + Push
git add .
git commit -m "Add dashboard layout"
git push -u origin feature/new-dashboard
# 3. สร้าง Pull Request บน GitHub
gh pr create --title "Add new dashboard" --body "Description here"
# 4. Code Review + Discussion
# ทีม Review โค้ด ให้ Feedback
# 5. Merge เข้า main (หลัง Review ผ่าน)
gh pr merge --squash
# 6. Deploy จาก main (อัตโนมัติผ่าน CI/CD)
# 7. ลบ Branch
git switch main
git pull
git branch -d feature/new-dashboard
git push origin --delete feature/new-dashboard
3. Trunk-Based Development
Trunk-Based Development (TBD) เป็น Strategy ที่ Google, Facebook และบริษัท Tech ขนาดใหญ่หลายแห่งใช้ แนวคิดหลักคือทุกคน Commit เข้า main (trunk) โดยตรง หรือใช้ Short-Lived Feature Branch ที่อยู่ไม่เกิน 1-2 วัน ข้อดีคือลด Merge Conflict และทำให้ Integration เร็วขึ้น แต่ต้องมี CI/CD ที่แข็งแกร่งและ Feature Flags
# Trunk-Based Development
# Feature Branch อยู่ไม่เกิน 1-2 วัน
# สร้าง Short-lived Branch
git switch -c feat/add-button
# ทำงาน 1-2 วัน
git add .
git commit -m "Add submit button"
git push -u origin feat/add-button
# สร้าง PR + Merge เร็ว (ภายใน 1 วัน)
gh pr create --title "Add submit button"
# หลัง Review -> Merge ทันที
# ใช้ Feature Flags สำหรับฟีเจอร์ที่ยังไม่เสร็จ
# if (featureFlag.isEnabled('new-dashboard')) {
# showNewDashboard();
# }
4. GitLab Flow
GitLab Flow เป็นการผสมผสานระหว่าง GitHub Flow กับ Environment Branch เหมาะสำหรับทีมที่ต้องการ Deploy ไปหลาย Environment เช่น staging, production ทำให้ควบคุมการ Promote โค้ดไปแต่ละ Environment ได้ชัดเจน
# GitLab Flow มี Environment Branches
# main -> staging -> production
# พัฒนาปกติเหมือน GitHub Flow
git switch -c feature/search
# ทำงาน...
# Merge เข้า main
# Promote ไป staging
git switch staging
git merge main
git push origin staging
# -> Deploy ไป Staging Server
# หลังทดสอบ Staging ผ่าน -> Promote ไป Production
git switch production
git merge staging
git push origin production
# -> Deploy ไป Production Server
| Strategy | เหมาะกับ | ข้อดี | ข้อเสีย |
|---|---|---|---|
| Git Flow | Mobile App, Release Cycle | ควบคุม Release ได้ดี | ซับซ้อน, Branch เยอะ |
| GitHub Flow | Web App, Deploy บ่อย | เรียบง่าย | ไม่รองรับ Multi-version |
| Trunk-Based | ทีมใหญ่, CI/CD แข็งแกร่ง | Integration เร็ว | ต้องมี Feature Flags |
| GitLab Flow | Multi-environment | ควบคุม Environment ได้ | ต้องจัดการหลาย Branch |
Merge vs Rebase — เมื่อไหร่ใช้อะไร
คำถามที่ถูกถามบ่อยที่สุดใน Git คือ ควรใช้ Merge หรือ Rebase ดี คำตอบสั้นๆ คือขึ้นอยู่กับสถานการณ์ ทั้งสองมีข้อดีข้อเสียต่างกัน การเข้าใจความแตกต่างจะช่วยให้เลือกใช้ได้ถูกต้อง
# Merge — สร้าง Merge Commit
git switch main
git merge feature/login
# ผลลัพธ์: สร้าง Merge commit ใหม่ เห็นประวัติว่า Branch แยกออกไปแล้ว Merge กลับ
# Rebase — ย้าย Base ของ Branch
git switch feature/login
git rebase main
# ผลลัพธ์: ย้าย Commits ของ feature/login ไปต่อจาก main ล่าสุด ประวัติเป็นเส้นตรง
# Fast-Forward Merge (หลัง Rebase)
git switch main
git merge feature/login # Fast-Forward เพราะ main ตรงกับ base ของ feature
| เกณฑ์ | Merge | Rebase |
|---|---|---|
| ประวัติ | เห็นการ Merge ชัดเจน | เป็นเส้นตรง สะอาด |
| ความปลอดภัย | ปลอดภัยกว่า ไม่เขียนประวัติใหม่ | เขียนประวัติใหม่ อันตรายถ้าใช้ผิด |
| Conflict | แก้ครั้งเดียว | อาจต้องแก้ทีละ Commit |
| เหมาะกับ | Public Branch, ทีมใหญ่ | Personal Branch, ก่อน PR |
Interactive Rebase — จัดเรียง Commit
Interactive Rebase เป็นเครื่องมือที่ทรงพลังที่สุดสำหรับจัดระเบียบ Commit History ก่อนที่จะ Push หรือสร้าง Pull Request ช่วยให้สามารถ Squash commits ที่เล็กๆ รวมกัน เปลี่ยน Commit Message แก้ไข Commit เก่า หรือจัดเรียงลำดับใหม่
# Interactive Rebase 5 Commits ล่าสุด
git rebase -i HEAD~5
# จะเปิด Editor แสดง:
# pick abc1234 Add user model
# pick def5678 Fix typo in user model
# pick ghi9012 Add user controller
# pick jkl3456 WIP: user validation
# pick mno7890 Complete user validation
# เปลี่ยน command ได้:
# pick = ใช้ commit นี้ (ไม่เปลี่ยน)
# reword = ใช้ commit แต่เปลี่ยน message
# edit = หยุดที่ commit นี้เพื่อแก้ไข
# squash = รวมกับ commit ก่อนหน้า (เก็บ message)
# fixup = รวมกับ commit ก่อนหน้า (ไม่เก็บ message)
# drop = ลบ commit นี้
# ตัวอย่าง: รวม commit ที่เกี่ยวข้อง
# pick abc1234 Add user model
# fixup def5678 Fix typo in user model <- รวมเข้า commit ก่อนหน้า
# pick ghi9012 Add user controller
# fixup jkl3456 WIP: user validation <- รวมเข้า commit ถัดไป
# pick mno7890 Complete user validation
# ผลลัพธ์: 5 commits -> 3 commits ที่สะอาด
# Squash ทุก Commit ใน Branch เป็น Commit เดียว
git rebase -i $(git merge-base HEAD main)
# เปลี่ยนทุกอันเป็น squash ยกเว้นอันแรก
# ถ้าเกิดปัญหาระหว่าง Rebase
git rebase --abort # ยกเลิกทั้งหมด
git rebase --continue # หลังแก้ Conflict แล้ว
git rebase --skip # ข้าม commit ที่มีปัญหา
Autosquash — Commit ที่เตรียมไว้สำหรับ Squash
# สร้าง Fixup Commit (เตรียมไว้สำหรับ Squash)
git commit --fixup=abc1234
# สร้าง Squash Commit
git commit --squash=abc1234
# Rebase แล้ว Auto-squash
git rebase -i --autosquash HEAD~5
# -> fixup! และ squash! commits จะถูกจัดเรียงอัตโนมัติ
# ตั้งค่าให้ autosquash เป็น default
git config --global rebase.autoSquash true
Cherry-pick — เลือก Commit เฉพาะ
Cherry-pick ใช้สำหรับคัดเลือก Commit จาก Branch หนึ่งไปใส่ใน Branch อื่น โดยไม่ต้อง Merge ทั้ง Branch เหมาะสำหรับกรณีที่ต้องการนำ Bug Fix จาก Feature Branch ไป Apply ใน main หรือ Hotfix Branch
# Cherry-pick commit เดียว
git switch main
git cherry-pick abc1234
# Cherry-pick หลาย commits
git cherry-pick abc1234 def5678 ghi9012
# Cherry-pick ช่วง commits
git cherry-pick abc1234..ghi9012 # ไม่รวม abc1234
git cherry-pick abc1234^..ghi9012 # รวม abc1234
# Cherry-pick แบบไม่ Commit (เอามาแค่ Stage)
git cherry-pick --no-commit abc1234
# ถ้ามี Conflict
git cherry-pick --continue # หลังแก้ Conflict
git cherry-pick --abort # ยกเลิก
# ดูว่า Commit นี้ถูก Cherry-pick มาจากไหน
git log --oneline --cherry-pick main...feature
Git Bisect — หา Bug ด้วยการค้นหาแบบ Binary Search
Git Bisect เป็นเครื่องมือที่ทรงพลังสำหรับหาว่า Bug ถูกนำเข้ามาที่ Commit ไหน โดยใช้หลักการ Binary Search ลดจำนวน Commit ที่ต้องตรวจลงครึ่งหนึ่งในแต่ละรอบ ถ้ามี 1,000 Commits สามารถหา Bug ได้ภายใน 10 ขั้นตอน
# เริ่มต้น Bisect
git bisect start
# บอกว่า Commit ปัจจุบันมี Bug
git bisect bad
# บอกว่า Commit ที่ยังทำงานปกติ (เช่น version 3 เดือนก่อน)
git bisect good abc1234
# Git จะ checkout ไปที่ commit กลาง
# ทดสอบว่า Bug มีหรือไม่
# ถ้ามี Bug:
git bisect bad
# ถ้าไม่มี Bug:
git bisect good
# ทำซ้ำจนกว่าจะเจอ commit ที่ทำให้เกิด Bug
# Git จะบอก: "abc1234 is the first bad commit"
# จบ Bisect
git bisect reset
# Bisect อัตโนมัติด้วย Script
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
git bisect run npm test # รัน test อัตโนมัติ
# Git จะหา Commit ที่ทำให้ test fail เอง!
Git Reflog — เซฟเนตของ Git
Reflog (Reference Log) บันทึกทุกการเปลี่ยนแปลงของ HEAD รวมถึง Commits ที่ถูก Reset, Rebase, หรือ Amend ถ้าคุณทำอะไรผิดพลาดใน Git เกือบทุกกรณีสามารถกู้คืนได้ด้วย Reflog ตราบใดที่ยังไม่ถูก Garbage Collect (ปกติ 90 วัน)
# ดู Reflog
git reflog
# abc1234 HEAD@{0}: commit: Add feature
# def5678 HEAD@{1}: rebase: squash
# ghi9012 HEAD@{2}: reset: moving to HEAD~3
# jkl3456 HEAD@{3}: commit: Old commit that was reset
# กู้คืน Commit ที่ถูก Reset
git reset --hard HEAD@{3}
# กู้คืน Branch ที่ถูกลบ
git reflog
# หา commit ล่าสุดของ Branch ที่ลบ
git switch -c recovered-branch abc1234
# กู้คืนจาก Rebase ที่ผิดพลาด
git reflog
# หา state ก่อน Rebase
git reset --hard HEAD@{5}
# Reflog ของ Branch เฉพาะ
git reflog show feature/login
# ดู Reflog พร้อมเวลา
git reflog --date=iso
Git Stash ขั้นสูง
Git Stash ไม่ได้มีแค่ save และ pop มีฟีเจอร์ขั้นสูงหลายอย่างที่ช่วยจัดการงานที่ยังไม่เสร็จได้ดีขึ้น
# Stash พร้อมชื่อ
git stash push -m "WIP: login form styling"
# Stash เฉพาะบางไฟล์
git stash push -m "Config changes" -- config.yml .env
# Stash รวม Untracked Files
git stash push -u -m "Include new files"
# Stash รวม Ignored Files
git stash push -a -m "Include everything"
# ดู Stash List
git stash list
# stash@{0}: On main: WIP: login form styling
# stash@{1}: On feature: Config changes
# ดูเนื้อหา Stash
git stash show -p stash@{0}
# Apply Stash เฉพาะอัน
git stash apply stash@{1}
# สร้าง Branch จาก Stash
git stash branch new-feature stash@{0}
# -> สร้าง branch + apply stash + ลบ stash
# ลบ Stash
git stash drop stash@{1} # ลบอันเดียว
git stash clear # ลบทั้งหมด
Git Worktree — ทำงานหลาย Branch พร้อมกัน
Git Worktree ช่วยให้สามารถ Checkout หลาย Branch พร้อมกันในคนละ Directory ไม่ต้อง Stash หรือ Commit ก่อนสลับ Branch อีกต่อไป เหมาะสำหรับกรณีที่ต้องสลับไปแก้ Bug ด่วนขณะที่กำลังทำ Feature อยู่
# สร้าง Worktree ใหม่
git worktree add ../hotfix-branch hotfix/fix-login
# -> สร้าง Directory ../hotfix-branch ที่ checkout branch hotfix/fix-login
# สร้าง Worktree พร้อม Branch ใหม่
git worktree add -b feature/new-api ../new-api-work
# ดู Worktree ทั้งหมด
git worktree list
# /home/user/project abc1234 [main]
# /home/user/hotfix-branch def5678 [hotfix/fix-login]
# /home/user/new-api-work ghi9012 [feature/new-api]
# ทำงานใน Worktree
cd ../hotfix-branch
# แก้ Bug...
git add . && git commit -m "Fix login crash"
git push
# กลับมาทำ Feature ต่อ
cd ../project
# โค้ดยังอยู่เหมือนเดิม ไม่ต้อง stash!
# ลบ Worktree
git worktree remove ../hotfix-branch
# ล้าง Worktree ที่ Directory ถูกลบไปแล้ว
git worktree prune
Git Hooks — อัตโนมัติทุกอย่าง
Git Hooks เป็น Script ที่รันอัตโนมัติเมื่อเกิด Event ต่างๆ ใน Git เช่น ก่อน Commit, หลัง Push หรือก่อน Merge ช่วยบังคับให้ทีมทำตามกฎที่ตกลงกัน เช่น รัน Linter ก่อน Commit หรือตรวจสอบ Commit Message Format
# Hooks อยู่ที่ .git/hooks/
# ไฟล์ต้องเป็น executable (chmod +x)
# pre-commit — รันก่อน Commit
# .git/hooks/pre-commit
#!/bin/sh
echo "Running linter..."
npm run lint
if [ $? -ne 0 ]; then
echo "Lint failed! Fix errors before committing."
exit 1
fi
echo "Running tests..."
npm test
if [ $? -ne 0 ]; then
echo "Tests failed! Fix tests before committing."
exit 1
fi
# commit-msg — ตรวจสอบ Commit Message
# .git/hooks/commit-msg
#!/bin/sh
MSG=$(cat "$1")
PATTERN="^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .+"
if ! echo "$MSG" | grep -qE "$PATTERN"; then
echo "Invalid commit message format!"
echo "Use: type(scope): description"
echo "Types: feat, fix, docs, style, refactor, test, chore"
exit 1
fi
# pre-push — รันก่อน Push
# .git/hooks/pre-push
#!/bin/sh
echo "Running full test suite..."
npm run test:all
if [ $? -ne 0 ]; then
echo "Tests failed! Cannot push."
exit 1
fi
Husky — จัดการ Hooks ในทีม
# ปัญหา: .git/hooks ไม่ถูก Track โดย Git
# แก้ด้วย Husky (สำหรับ Node.js project)
# ติดตั้ง Husky
npm install -D husky
npx husky init
# สร้าง pre-commit hook
echo "npm run lint && npm test" > .husky/pre-commit
# สร้าง commit-msg hook
echo 'npx commitlint --edit $1' > .husky/commit-msg
# ติดตั้ง commitlint
npm install -D @commitlint/cli @commitlint/config-conventional
# commitlint.config.js
echo "module.exports = { extends: ['@commitlint/config-conventional'] }" > commitlint.config.js
# ทุกคนในทีมจะมี Hooks เหมือนกันหลัง npm install
Conventional Commits — มาตรฐาน Commit Message
Conventional Commits เป็นข้อตกลงเรื่องรูปแบบ Commit Message ที่ชัดเจน ทำให้สามารถอ่าน Changelog อัตโนมัติ คำนวณ Version ตาม Semantic Versioning และทำให้ประวัติ Commit มีความหมายและค้นหาได้
# รูปแบบ: type(scope): description
# Types:
# feat — ฟีเจอร์ใหม่ (MINOR version)
# fix — แก้ Bug (PATCH version)
# docs — แก้เอกสาร
# style — แก้ formatting (ไม่กระทบ logic)
# refactor — ปรับโครงสร้างโค้ด
# test — เพิ่ม/แก้ test
# chore — งานอื่นๆ (build, dependencies)
# perf — ปรับปรุง Performance
# ci — แก้ CI/CD
# ตัวอย่าง:
git commit -m "feat(auth): add Google OAuth login"
git commit -m "fix(api): handle null response from payment gateway"
git commit -m "docs(readme): update installation instructions"
git commit -m "refactor(user): extract validation logic to separate module"
git commit -m "test(cart): add unit tests for discount calculation"
# Breaking Change (MAJOR version)
git commit -m "feat(api)!: change response format to JSON:API"
# หรือ
git commit -m "feat(api): change response format
BREAKING CHANGE: Response format changed from custom to JSON:API.
All clients must update their parsers."
Semantic Versioning กับ Git Tags
# Semantic Versioning: MAJOR.MINOR.PATCH
# MAJOR — เปลี่ยนแปลงที่ไม่ Compatible
# MINOR — เพิ่ม Feature (ยังคง Compatible)
# PATCH — แก้ Bug
# สร้าง Tag
git tag v1.0.0
git tag -a v1.0.0 -m "Release version 1.0.0" # Annotated Tag (แนะนำ)
# สร้าง Tag จาก Commit เก่า
git tag -a v0.9.0 abc1234 -m "Retroactive tag"
# Push Tags
git push origin v1.0.0 # Push tag เดียว
git push origin --tags # Push ทุก tag
# ดู Tags
git tag # ทั้งหมด
git tag -l "v1.*" # เฉพาะ v1.x
git show v1.0.0 # รายละเอียด tag
# ลบ Tag
git tag -d v1.0.0 # ลบ Local
git push origin :v1.0.0 # ลบ Remote
# Auto-versioning ด้วย standard-version
npx standard-version # คำนวณ version จาก commits
npx standard-version --first-release # Release แรก
Monorepo vs Polyrepo
การเลือกโครงสร้าง Repository เป็นอีกหนึ่งการตัดสินใจสำคัญ Monorepo คือการเก็บทุกโปรเจกต์ไว้ใน Repository เดียว ส่วน Polyrepo คือแยก Repository ต่อโปรเจกต์ ทั้งสองมีข้อดีข้อเสียต่างกัน
| เกณฑ์ | Monorepo | Polyrepo |
|---|---|---|
| Code Sharing | ง่าย อยู่ที่เดียว | ต้องผ่าน Package Manager |
| Dependency | อัพเดทพร้อมกัน | จัดการแยก |
| CI/CD | ซับซ้อนกว่า (ต้อง detect changes) | เรียบง่าย |
| Scalability | Repo ใหญ่มาก (ช้า) | แต่ละ Repo เล็ก (เร็ว) |
| ใครใช้ | Google, Meta, Microsoft | ส่วนใหญ่ทั่วไป |
# Monorepo Tools ยอดนิยม:
# - Turborepo (Vercel) — เร็ว, cache build
# - Nx (Nrwl) — สำหรับ Angular/React/Node
# - Lerna — สำหรับ JavaScript/TypeScript
# - Bazel (Google) — สำหรับ Multi-language
# ตัวอย่างโครงสร้าง Monorepo
# my-monorepo/
# packages/
# frontend/
# backend/
# shared-utils/
# apps/
# web/
# mobile/
# package.json (root)
Git Submodules และ Subtrees
# Submodule — Reference ไปยัง Repository อื่น
git submodule add https://github.com/user/lib.git libs/lib
git submodule update --init --recursive
# Clone repo ที่มี Submodules
git clone --recursive https://github.com/user/project.git
# อัพเดท Submodule
git submodule update --remote
# Subtree — Copy โค้ดจาก Repository อื่นเข้ามา
git subtree add --prefix=libs/lib https://github.com/user/lib.git main --squash
# อัพเดท Subtree
git subtree pull --prefix=libs/lib https://github.com/user/lib.git main --squash
# ข้อแตกต่าง:
# Submodule: เก็บแค่ Reference, ต้อง init แยก
# Subtree: Copy โค้ดมาทั้งหมด, ใช้ได้ทันที
Git LFS — จัดการไฟล์ขนาดใหญ่
Git ไม่ได้ออกแบบมาสำหรับไฟล์ขนาดใหญ่ เช่น รูปภาพ วิดีโอ หรือ Binary ถ้าเก็บไฟล์ขนาดใหญ่ใน Git ปกติ Repository จะใหญ่ขึ้นเรื่อยๆ และ Clone ช้ามาก Git LFS (Large File Storage) แก้ปัญหานี้โดยเก็บเฉพาะ Pointer ใน Git แล้วเก็บไฟล์จริงที่ LFS Server
# ติดตั้ง Git LFS
git lfs install
# Track ไฟล์ตาม Pattern
git lfs track "*.psd"
git lfs track "*.zip"
git lfs track "assets/**/*.png"
# ดูไฟล์ที่ Track
git lfs ls-files
# .gitattributes จะถูกสร้างอัตโนมัติ
# *.psd filter=lfs diff=lfs merge=lfs -text
# *.zip filter=lfs diff=lfs merge=lfs -text
# Commit .gitattributes ก่อน!
git add .gitattributes
git commit -m "chore: configure Git LFS"
# จากนั้นใช้ Git ตามปกติ
git add large-file.psd
git commit -m "Add design file"
git push # ไฟล์จะถูกอัพโหลดไป LFS Server
Resolving Merge Conflicts — กลยุทธ์การแก้ Conflict
Merge Conflict เป็นสิ่งที่หลีกเลี่ยงไม่ได้เมื่อทำงานเป็นทีม แต่ถ้ามีกลยุทธ์ที่ดี จะสามารถลดจำนวน Conflict และแก้ไขได้อย่างรวดเร็ว
# Conflict Markers
# <<<<<<< HEAD
# Your changes (current branch)
# =======
# Their changes (incoming branch)
# >>>>>>> feature/login
# กลยุทธ์ลด Conflict:
# 1. Merge/Rebase main เข้า Feature Branch บ่อยๆ
git switch feature/login
git merge main # ทำทุกวัน
# 2. แยก File ให้เล็ก ไม่ให้หลายคนแก้ไฟล์เดียวกัน
# 3. ใช้ Merge Tool
git mergetool # เปิด Visual Merge Tool
# ตั้งค่า VS Code เป็น Merge Tool
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait --merge $REMOTE $LOCAL $BASE $MERGED'
# 4. เลือก Strategy
git merge -X ours feature/login # ถ้า conflict ใช้ฝั่งเรา
git merge -X theirs feature/login # ถ้า conflict ใช้ฝั่งเขา
# 5. Rerere — จำวิธีแก้ Conflict
git config --global rerere.enabled true
# Git จะจำวิธีที่คุณแก้ Conflict และ apply อัตโนมัติถ้าเจอ pattern เดิม
.gitattributes ขั้นสูง
# .gitattributes — ควบคุมวิธีที่ Git จัดการไฟล์
# Line Ending (สำคัญมากสำหรับทีมที่ใช้หลาย OS)
* text=auto # ให้ Git detect อัตโนมัติ
*.sh text eol=lf # Shell script ใช้ LF เสมอ
*.bat text eol=crlf # Batch file ใช้ CRLF เสมอ
# Binary Files (ไม่ต้อง diff)
*.png binary
*.jpg binary
*.ico binary
# Lock Files (ไม่ merge อัตโนมัติ)
package-lock.json merge=ours
yarn.lock merge=ours
# Custom Diff
*.csv diff=csv
*.md diff=markdown
.gitignore ขั้นสูง
# .gitignore ที่ครอบคลุม
# Dependencies
node_modules/
vendor/
__pycache__/
*.pyc
.venv/
# Build Output
dist/
build/
*.o
*.so
*.dll
# Environment
.env
.env.local
.env.production
# IDE
.idea/
.vscode/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
desktop.ini
# Logs
*.log
logs/
# Testing
coverage/
.nyc_output/
# Global .gitignore (ไม่ต้องใส่ทุก Project)
git config --global core.excludesfile ~/.gitignore_global
# ดูว่าทำไมไฟล์ถูก ignore
git check-ignore -v filename
# Track ไฟล์ที่ถูก ignore (ไม่แนะนำ)
git add -f secret-but-needed.txt
# ลบไฟล์จาก Git แต่เก็บไว้ใน Disk
git rm --cached secret.env
Code Review Workflow ที่ดี
Code Review เป็นส่วนสำคัญของการทำงานเป็นทีม Pull Request ที่ดีจะทำให้ Review ง่ายและเร็วขึ้น ลดโอกาสที่ Bug จะหลุดไป Production
# PR ที่ดีควรมี:
# 1. ขนาดเล็ก (ไม่เกิน 300-400 บรรทัด)
# 2. ทำเรื่องเดียว (Single Responsibility)
# 3. มี Description ชัดเจน
# 4. มี Tests
# 5. ผ่าน CI/CD
# สร้าง PR ด้วย gh CLI
gh pr create --title "feat(auth): add Google OAuth login" --body "## What
- Added Google OAuth2 login flow
- Integrated with existing user system
## Why
Users requested social login (Issue #123)
## Testing
- Unit tests added
- Manual testing on staging
## Screenshots
[before/after screenshots]"
# Review PR
gh pr review 123 --approve
gh pr review 123 --request-changes --body "Please fix..."
gh pr review 123 --comment --body "Looks good overall"
# Merge PR
gh pr merge 123 --squash --delete-branch
# ดู PR diff
gh pr diff 123
สรุป
Git ขั้นสูงเป็นทักษะที่แยก Junior Developer ออกจาก Senior Developer การเข้าใจ Branching Strategy ที่เหมาะสม การใช้ Interactive Rebase เพื่อจัดระเบียบ Commit History การใช้ Cherry-pick, Bisect และ Reflog อย่างคล่องแคล่ว ตลอดจนการตั้งค่า Git Hooks และ Conventional Commits จะทำให้ทีมทำงานได้อย่างมีประสิทธิภาพและมีมาตรฐาน
สิ่งสำคัญที่สุดคือการเลือก Workflow ที่เหมาะกับขนาดและลักษณะของทีม ไม่มี Strategy ไหนที่ดีที่สุดสำหรับทุกสถานการณ์ ทีมเล็กที่ Deploy บ่อยอาจเหมาะกับ GitHub Flow ทีมใหญ่ที่มี Release Cycle อาจเหมาะกับ Git Flow และทีมที่ต้องการ Integration เร็วอาจเหมาะกับ Trunk-Based Development ลองนำไปปรับใช้กับทีมของคุณ แล้วจะเห็นว่าการทำงานร่วมกันจะราบรื่นขึ้นอย่างมาก
