← กลับหน้าหลัก

Git สำหรับมือใหม่ 30 คำสั่งที่ต้องรู้

โดย อ.บอม (SiamCafe Admin) | 11/02/2026 | Programming | 3,571 คำ
Git สำหรับมือใหม่ 30 คำสั่งที่ต้องรู้

บทนำ: Git และ Version Control โลกที่โปรแกรมเมอร์ขาดไม่ได้

Git ไม่ใช่แค่เครื่องมือ แต่เป็นเหมือนเพื่อนคู่คิดของโปรแกรมเมอร์ทุกคนครับ ลองนึกภาพว่าคุณกำลังสร้างบ้านหลังใหญ่ ถ้าไม่มีพิมพ์เขียว ไม่มีแผนผัง คุณจะสร้างมันได้ยังไง? Git ก็เหมือนพิมพ์เขียวของโค้ดเรานั่นแหละ ช่วยให้เราจัดการ แก้ไข และย้อนกลับไปดูโค้ดในอดีตได้เสมอ แถมยังทำงานร่วมกับเพื่อนร่วมทีมได้อย่างราบรื่นอีกด้วย ใครที่ยังไม่เคยลองใช้ Git ผมบอกเลยว่าพลาดมาก! ในโลกของการพัฒนาซอฟต์แวร์ Version Control System (VCS) หรือระบบควบคุมเวอร์ชันมีความสำคัญอย่างมาก และ Git ก็คือพระเอกของ VCS ในยุคนี้เลยครับ ลองดูสถิติจาก Stack Overflow Developer Survey ปีล่าสุดสิครับ Git ถูกใช้โดยนักพัฒนาซอฟต์แวร์กว่า 90% ทั่วโลก! นั่นแสดงให้เห็นว่า Git ไม่ได้เป็นแค่เทรนด์ แต่เป็นมาตรฐานที่ทุกคนต้องเรียนรู้เพื่อที่จะทำงานในสายงานนี้ได้อย่างมีประสิทธิภาพ ผมเองก็เป็นคนหนึ่งที่ใช้ Git มาตั้งแต่สมัยเรียนมหาวิทยาลัย ช่วงแรกๆ ก็งงๆ ว่ามันทำงานยังไง แต่พอเริ่มเข้าใจคอนเซ็ปต์แล้ว ชีวิตก็ง่ายขึ้นเยอะเลยครับ จำได้ว่าตอนทำโปรเจกต์จบ Git ช่วยชีวิตผมไว้หลายครั้ง เพราะสามารถย้อนกลับไปแก้ไขโค้ดที่ผิดพลาดได้โดยไม่ต้องกลัวว่าจะทำให้โปรเจกต์พัง Git ไม่ได้จำกัดอยู่แค่การพัฒนาซอฟต์แวร์นะครับ ผมเคยเห็นเพื่อนที่ทำงานด้านเอกสาร ใช้ Git ในการจัดการไฟล์เอกสารด้วยซ้ำ เพราะมันช่วยให้ติดตามการเปลี่ยนแปลงของเอกสารได้อย่างละเอียด แถมยังสามารถทำงานร่วมกับคนอื่นได้พร้อมๆ กันอีกด้วย พูดง่ายๆ คือ Git เป็นเครื่องมือที่ช่วยให้เราทำงานได้อย่างเป็นระบบ ลดความผิดพลาด และเพิ่มประสิทธิภาพในการทำงาน ไม่ว่าคุณจะเป็นโปรแกรมเมอร์ นักเขียน หรือใครก็ตามที่ต้องจัดการไฟล์และทำงานร่วมกับคนอื่น Git จะเป็นเครื่องมือที่มีประโยชน์อย่างแน่นอนครับ

พื้นฐานความรู้เกี่ยวกับ Git ที่ควรรู้

ก่อนที่เราจะไปลงมือใช้คำสั่ง Git ต่างๆ เรามาทำความเข้าใจพื้นฐานที่สำคัญกันก่อนดีกว่าครับ การเข้าใจหลักการทำงานของ Git จะช่วยให้เราใช้งานมันได้อย่างมีประสิทธิภาพมากขึ้น และแก้ปัญหาที่อาจเกิดขึ้นได้ง่ายขึ้นด้วย

Repository (คลังเก็บโค้ด) คืออะไร?

Repository หรือเรียกสั้นๆ ว่า "Repo" คือที่เก็บโค้ดและประวัติการเปลี่ยนแปลงทั้งหมดของโปรเจกต์เราครับ ลองจินตนาการว่ามันคือโฟลเดอร์พิเศษที่ Git คอยเฝ้าดูอยู่ตลอดเวลา เมื่อเรามีการแก้ไขโค้ด Git ก็จะบันทึกการเปลี่ยนแปลงเหล่านั้นไว้ ทำให้เราสามารถย้อนกลับไปดูโค้ดในอดีตได้เสมอ Repository มีอยู่ 2 แบบหลักๆ คือ Local Repository (Repo ที่อยู่ในเครื่องเรา) และ Remote Repository (Repo ที่อยู่บน Server เช่น GitHub, GitLab, Bitbucket) เวลาเราทำงาน เราจะแก้ไขโค้ดใน Local Repo ก่อน แล้วค่อย Push (ส่ง) การเปลี่ยนแปลงเหล่านั้นไปยัง Remote Repo เพื่อให้คนอื่นสามารถเข้าถึงและทำงานร่วมกันได้ การสร้าง Repository ทำได้ง่ายมากครับ เพียงแค่เปิด Terminal หรือ Command Prompt แล้วพิมพ์คำสั่ง git init ในโฟลเดอร์โปรเจกต์ของเรา Git ก็จะสร้างโฟลเดอร์พิเศษชื่อ .git ขึ้นมา ซึ่งเป็นที่เก็บข้อมูลทั้งหมดของ Repository
$ cd my-project
$ git init
Initialized empty Git repository in /Users/yourname/my-project/.git/
อย่าลืมว่าโฟลเดอร์ .git นี้สำคัญมากนะครับ ห้ามลบหรือแก้ไขไฟล์ในนั้นโดยเด็ดขาด! เพราะมันคือหัวใจหลักของ Git Repository ของเราเลย

Staging Area และ Commit คืออะไร?

Staging Area หรือ Index คือพื้นที่พักโค้ดก่อนที่จะทำการ Commit ครับ ลองนึกภาพว่าเรากำลังจะส่งของขวัญให้เพื่อน เราต้องห่อของขวัญนั้นก่อนที่จะส่งใช่ไหมครับ? Staging Area ก็เหมือนกับการห่อของขวัญนั่นแหละ เป็นการเตรียมโค้ดที่เราต้องการจะบันทึกก่อนที่จะ Commit การ Commit คือการบันทึกการเปลี่ยนแปลงโค้ดที่เราได้ Staging ไว้ลงใน Repository ครับ Commit แต่ละครั้งจะมี Message อธิบายว่าเราได้แก้ไขอะไรไปบ้าง Message ที่ดีจะช่วยให้เราและคนอื่นเข้าใจได้ง่ายว่า Commit นี้มีจุดประสงค์อะไร คำสั่งที่ใช้ในการ Staging คือ git add และคำสั่งที่ใช้ในการ Commit คือ git commit ตัวอย่างเช่น
$ git add .  # Stage ไฟล์ทั้งหมดที่เปลี่ยนแปลง
$ git commit -m "แก้ไขบั๊กในส่วนของการแสดงผล" # Commit พร้อม Message อธิบาย
Message ใน Commit สำคัญมากนะครับ พยายามเขียนให้กระชับ ชัดเจน และสื่อถึงสิ่งที่เปลี่ยนแปลงไปจริงๆ จะช่วยให้การทำงานเป็นทีมง่ายขึ้นเยอะเลย ผมเคยเจอ Commit Message ที่เขียนว่า "แก้ไข" อย่างเดียว บอกเลยว่าปวดหัวมาก!

Branching และ Merging คืออะไร?

Branching คือการแตกกิ่งก้านของโค้ดออกจาก Main Branch (หรือ Master Branch ใน Git เวอร์ชั่นเก่า) เพื่อทำงานในส่วนต่างๆ ของโปรเจกต์โดยไม่กระทบกับโค้ดหลัก ลองนึกภาพว่าเรากำลังสร้างบ้าน ถ้าเราต้องการจะทดลองทาสีห้องใหม่ เราคงไม่อยากทาสีทับสีเก่าเลยใช่ไหมครับ? เราก็จะสร้างห้องจำลองขึ้นมาเพื่อทดลองทาสีก่อน Branching ช่วยให้เราสามารถทำงานหลายๆ อย่างไปพร้อมๆ กันได้ โดยแต่ละ Branch จะมีโค้ดที่เป็นอิสระจากกัน เมื่อเราทำงานใน Branch เสร็จแล้ว เราสามารถ Merge (รวม) Branch นั้นกลับเข้าไปใน Main Branch ได้ คำสั่งที่ใช้ในการสร้าง Branch คือ git branch คำสั่งที่ใช้ในการเปลี่ยน Branch คือ git checkout และคำสั่งที่ใช้ในการ Merge คือ git merge ตัวอย่างเช่น
$ git branch feature/new-login  # สร้าง Branch ใหม่ชื่อ feature/new-login
$ git checkout feature/new-login # เปลี่ยนไปใช้ Branch feature/new-login
$ git merge feature/new-login # รวม Branch feature/new-login เข้ากับ Branch ปัจจุบัน
การใช้ Branching อย่างมีประสิทธิภาพเป็นทักษะที่สำคัญมากในการทำงานเป็นทีม เพราะมันช่วยให้เราสามารถทำงานไปพร้อมๆ กันได้โดยไม่เกิด Conflict (ความขัดแย้ง) ของโค้ด

🎬 YouTube @icafefx

วิธีติดตั้งและใช้งาน Git เบื้องต้น

การติดตั้ง Git นั้นง่ายมากครับ ขึ้นอยู่กับระบบปฏิบัติการที่เราใช้ | ระบบปฏิบัติการ | วิธีการติดตั้ง | | -------------- | -------------------------------------------------------------------------------------------------------------------- | | Windows | ดาวน์โหลด Installer จาก [https://git-scm.com/download/win](https://git-scm.com/download/win) แล้วติดตั้งตามขั้นตอน | | macOS | ติดตั้งผ่าน Homebrew: `brew install git` หรือดาวน์โหลด Installer จาก [https://git-scm.com/download/mac](https://git-scm.com/download/mac) | | Linux | ใช้ Package Manager ของ Distribution นั้นๆ เช่น `apt install git` (Debian/Ubuntu) หรือ `yum install git` (CentOS/RHEL) | เมื่อติดตั้ง Git เสร็จแล้ว เราสามารถตรวจสอบเวอร์ชันของ Git ได้โดยพิมพ์คำสั่ง git --version ใน Terminal หรือ Command Prompt
$ git --version
git version 2.39.2
หลังจากติดตั้ง Git เรียบร้อยแล้ว สิ่งแรกที่เราต้องทำคือการตั้งค่า Username และ Email ของเรา เพื่อให้ Git รู้ว่าใครเป็นคน Commit โค้ด
$ git config --global user.name "Your Name"
$ git config --global user.email "your.email@example.com"
ตรงนี้สำคัญมากนะครับ เพราะ Username และ Email ของเราจะถูกบันทึกไว้ใน Commit ทุกครั้ง ทำให้คนอื่นรู้ว่าใครเป็นคนแก้ไขโค้ดส่วนไหน ลองดูตัวอย่างการใช้งาน Git แบบง่ายๆ ตั้งแต่เริ่มต้นจนถึงการ Push โค้ดขึ้น GitHub ครับ
สมมติว่าเรามีโปรเจกต์ใหม่ชื่อ "my-website" เราจะเริ่มต้นด้วยการสร้าง Repository ในเครื่องของเราก่อน
$ mkdir my-website
$ cd my-website
$ git init
Initialized empty Git repository in /Users/yourname/my-website/.git/
จากนั้นเราจะสร้างไฟล์ HTML ง่ายๆ ชื่อ "index.html"
<html>
<head>
  <title>My Website</title>
</head>
<body>
  <h1>Hello, world!</h1>
</body>
</html>
แล้วทำการ Staging และ Commit ไฟล์นี้
$ git add index.html
$ git commit -m "สร้างไฟล์ index.html"
[master (root-commit) a1b2c3d] สร้างไฟล์ index.html
 1 file changed, 9 insertions(+)
 create mode 100644 index.html
ตอนนี้โค้ดของเราอยู่ใน Local Repository แล้ว ถ้าเราต้องการ Push โค้ดขึ้น GitHub เราจะต้องสร้าง Repository บน GitHub ก่อน จากนั้นก็ Add Remote Repository เข้ามาใน Local Repository ของเรา
$ git remote add origin git@github.com:yourusername/my-website.git
$ git push -u origin master
คำสั่ง git remote add origin จะเพิ่ม Remote Repository ชื่อ "origin" ซึ่งเป็น URL ของ Repository บน GitHub ของเรา ส่วนคำสั่ง git push -u origin master จะ Push โค้ดจาก Local Branch "master" ขึ้นไปยัง Remote Branch "master" บน GitHub
นี่เป็นเพียงตัวอย่างง่ายๆ นะครับ แต่หวังว่ามันจะช่วยให้คุณเห็นภาพรวมของการใช้งาน Git ได้ชัดเจนขึ้น ในส่วนต่อไปเราจะมาเจาะลึกคำสั่ง Git ที่สำคัญๆ กันครับ

เทคนิคขั้นสูง / Configuration

Git ไม่ได้มีแค่คำสั่งพื้นฐานที่เราใช้กันทุกวันเท่านั้นนะ จริงๆ แล้วมันมีอะไรที่ซับซ้อนและมีประโยชน์อีกเยอะเลย โดยเฉพาะเรื่องของการปรับแต่งค่าต่างๆ หรือ Configuration เพื่อให้ Git ทำงานได้ตรงใจเรามากขึ้น หรือเพื่อเพิ่มประสิทธิภาพในการทำงานร่วมกับคนอื่นๆ ในทีม ลองมาดูเทคนิคและ Configuration ที่น่าสนใจกันครับ

การตั้งค่า Git Configuration

การปรับแต่งค่า Git Configuration เป็นเรื่องที่สำคัญมาก เพราะมันจะช่วยให้เราสามารถปรับ Git ให้เข้ากับการทำงานของเราได้ดีที่สุด Git Configuration สามารถปรับได้ 3 ระดับ คือ `system`, `global` และ `local` ซึ่งแต่ละระดับก็จะมีผลต่อการใช้งานที่แตกต่างกันไป * **System:** การตั้งค่าระดับนี้จะมีผลกับผู้ใช้งานทุกคนบนเครื่องคอมพิวเตอร์นั้นๆ ซึ่งโดยปกติแล้วจะไม่ค่อยมีการปรับแต่งอะไรมากนัก เพราะมันเป็นการตั้งค่าในระดับระบบ * **Global:** การตั้งค่าระดับนี้จะมีผลกับผู้ใช้งานปัจจุบันเท่านั้น โดยจะถูกบันทึกไว้ในไฟล์ `.gitconfig` ใน Home Directory ของเรา นี่คือระดับที่เรามักจะใช้ปรับแต่งค่าต่างๆ มากที่สุด เช่น ชื่อผู้ใช้, อีเมล หรือ alias ต่างๆ * **Local:** การตั้งค่าระดับนี้จะมีผลกับ Repository นั้นๆ เท่านั้น โดยจะถูกบันทึกไว้ในไฟล์ `.git/config` ภายใน Repository นั้นๆ เหมาะสำหรับการตั้งค่าเฉพาะเจาะจงสำหรับโปรเจกต์นั้นๆ เช่น URL ของ Remote Repository เราสามารถใช้คำสั่ง `git config` เพื่อดูและแก้ไขค่า Configuration ได้ ตัวอย่างเช่น
git config --global user.name "Siam Cafe"
git config --global user.email "siam@siamcafe.net"
git config --local core.editor "vim"
คำสั่งเหล่านี้จะทำการตั้งชื่อผู้ใช้เป็น "Siam Cafe", อีเมลเป็น "siam@siamcafe.net" และ Editor ที่ใช้เป็น `vim` ตามลำดับ การตั้งค่าเหล่านี้จะช่วยให้ Git สามารถระบุตัวตนของเราในการ Commit และ Merge ได้อย่างถูกต้อง

การสร้าง Git Aliases

Git Aliases คือการสร้างชื่อย่อสำหรับคำสั่ง Git ที่เราใช้บ่อยๆ ซึ่งจะช่วยให้เราประหยัดเวลาในการพิมพ์คำสั่งได้มาก ลองคิดดูนะ ถ้าเราต้องพิมพ์ `git commit -m "แก้ไขบั๊ก"` ทุกครั้ง มันก็คงจะน่าเบื่อไม่น้อย แต่ถ้าเราสร้าง Alias ไว้ เราก็แค่พิมพ์ `git cm "แก้ไขบั๊ก"` ก็พอแล้ว การสร้าง Alias สามารถทำได้โดยใช้คำสั่ง `git config` เช่นกัน ตัวอย่างเช่น
git config --global alias.cm 'commit -m'
git config --global alias.st 'status'
git config --global alias.br 'branch'
git config --global alias.co 'checkout'
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
หลังจากสร้าง Alias แล้ว เราก็สามารถใช้งานได้เลย เช่น `git cm "แก้ไขบั๊ก"`, `git st`, `git br` หรือ `git lg` ซึ่งคำสั่ง `git lg` เนี่ย ผมชอบมาก เพราะมันจะแสดง Log ในรูปแบบ Graph ที่อ่านง่ายสุดๆ ใครที่ยังไม่เคยลองใช้ ลองเอาไปปรับใช้ดูนะครับ รับรองว่าจะติดใจ

Git Hooks

Git Hooks คือ Script ที่ Git จะเรียกใช้งานโดยอัตโนมัติเมื่อมีเหตุการณ์บางอย่างเกิดขึ้นใน Repository เช่น ก่อน Commit, หลัง Commit, ก่อน Push เป็นต้น เราสามารถใช้ Hooks เพื่อตรวจสอบโค้ด, รัน Test หรือทำอะไรก็ได้ที่เราต้องการก่อนที่จะทำการ Commit หรือ Push โค้ดขึ้นไป Hooks จะอยู่ใน Directory `.git/hooks` ภายใน Repository ซึ่งจะมีไฟล์ตัวอย่างให้เราอยู่แล้ว เช่น `pre-commit.sample`, `post-commit.sample` เป็นต้น เราสามารถแก้ไขไฟล์เหล่านี้ หรือสร้างไฟล์ใหม่ที่มีชื่อตรงกับ Hook ที่เราต้องการใช้งานได้เลย ตัวอย่างเช่น ถ้าเราต้องการให้ Git ตรวจสอบ Coding Style ก่อนที่จะทำการ Commit เราสามารถสร้างไฟล์ `pre-commit` ที่มีเนื้อหาประมาณนี้
#!/bin/sh
echo "Checking coding style..."
# Add your coding style check command here
# If the check fails, exit with a non-zero code
อย่าลืมให้ Permission ในการ Execute กับไฟล์ Hook ด้วยนะ
chmod +x .git/hooks/pre-commit
เมื่อเราทำการ Commit Git ก็จะรัน Script นี้ก่อน ถ้า Script ทำงานผิดพลาด (Exit Code ไม่ใช่ 0) Git ก็จะไม่ยอมให้ Commit

ตัวอย่าง Configuration ที่ใช้งานจริง

นี่คือตัวอย่าง Configuration ที่ผมใช้เป็นประจำ ซึ่งอาจจะมีประโยชน์สำหรับใครหลายๆ คน
[user]
    name = Siam Cafe
    email = siam@siamcafe.net
[core]
    editor = vim
[alias]
    cm = commit -m
    st = status
    br = branch
    co = checkout
    lg = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative
    df = diff
    hist = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short
    last = log -1 HEAD --stat
[pull]
    rebase = false
[push]
    default = simple
[color]
    ui = true
[interactive]
    diffFilter = /usr/bin/diffcolordiff
Configuration นี้จะทำการตั้งชื่อผู้ใช้, อีเมล, Editor และ Alias ต่างๆ ที่ผมใช้บ่อยๆ นอกจากนี้ยังมีการตั้งค่าสีสันใน Terminal ให้ดูง่ายขึ้นด้วย ใครที่อยากลองเอาไปปรับใช้ ก็สามารถ Copy ไปใส่ในไฟล์ `.gitconfig` ของตัวเองได้เลย

เปรียบเทียบ

Git เป็น Version Control System ที่ได้รับความนิยมอย่างมาก แต่ก็ยังมีเครื่องมืออื่นๆ ที่ใช้ในการจัดการ Source Code อีกมากมาย ในส่วนนี้เราจะมาเปรียบเทียบ Git กับเครื่องมืออื่นๆ เพื่อให้เห็นข้อดีข้อเสียของแต่ละตัว และช่วยให้เราเลือกเครื่องมือที่เหมาะสมกับการใช้งานของเรามากที่สุด

Git vs. SVN (Subversion)

SVN เป็น Version Control System ที่ได้รับความนิยมมาก่อน Git แต่ปัจจุบัน Git ได้รับความนิยมมากกว่า SVN อย่างเห็นได้ชัด ลองมาดูตารางเปรียบเทียบกัน | คุณสมบัติ | Git | SVN | | ----------------- | ----------------------------------- | --------------------------------- | | Architecture | Distributed | Centralized | | Branching/Merging | ง่ายและรวดเร็ว | ซับซ้อนและช้า | | Offline Mode | รองรับการทำงาน Offline อย่างเต็มที่ | ไม่รองรับการทำงาน Offline | | Performance | เร็วกว่า SVN | ช้ากว่า Git | | Complexity | ซับซ้อนกว่า SVN | ง่ายกว่า Git | จากตารางจะเห็นได้ว่า Git มีข้อดีหลายอย่างเหนือกว่า SVN โดยเฉพาะในเรื่องของ Architecture ที่เป็นแบบ Distributed ทำให้การ Branching/Merging ทำได้ง่ายและรวดเร็ว นอกจากนี้ Git ยังรองรับการทำงาน Offline ได้อย่างเต็มที่ ซึ่งเป็นข้อได้เปรียบอย่างมากในการทำงานแบบ Remote อย่างไรก็ตาม SVN ก็ยังมีข้อดีในเรื่องของความง่ายในการใช้งาน เหมาะสำหรับโปรเจกต์ขนาดเล็กที่ไม่ต้องการความซับซ้อนมากนัก

Git vs. Mercurial

Mercurial เป็น Distributed Version Control System ที่คล้ายกับ Git แต่มีเป้าหมายที่จะทำให้ใช้งานง่ายกว่า Git ลองมาดูตารางเปรียบเทียบกัน | คุณสมบัติ | Git | Mercurial | | ----------------- | ----------------------------------- | ----------------------------------- | | Complexity | ซับซ้อนกว่า Mercurial | ง่ายกว่า Git | | Performance | เร็วกว่า Mercurial | ช้ากว่า Git | | Community | ใหญ่กว่า Mercurial | เล็กกว่า Git | | Tooling | มีเครื่องมือและ Plugin มากกว่า | มีเครื่องมือและ Plugin น้อยกว่า | จากตารางจะเห็นได้ว่า Mercurial มีข้อดีในเรื่องของความง่ายในการใช้งาน เหมาะสำหรับผู้ที่เริ่มต้นใช้งาน Version Control System แต่ Git มีข้อได้เปรียบในเรื่องของ Performance, Community และ Tooling ซึ่งทำให้ Git เป็นตัวเลือกที่ดีกว่าสำหรับโปรเจกต์ขนาดใหญ่และซับซ้อน จริงๆ แล้วทั้ง Git และ Mercurial ต่างก็เป็นเครื่องมือที่ดีทั้งคู่ การเลือกใช้เครื่องมือไหนก็ขึ้นอยู่กับความชอบและความถนัดของแต่ละคน

ข้อควรระวัง / Troubleshooting

การใช้ Git ก็เหมือนกับการใช้เครื่องมืออื่นๆ ที่อาจจะเจอปัญหาหรือข้อผิดพลาดได้ ในส่วนนี้เราจะมาดูข้อควรระวังและวิธีการแก้ไขปัญหาที่อาจจะเกิดขึ้นในการใช้งาน Git เพื่อให้เราสามารถแก้ไขปัญหาได้อย่างรวดเร็วและมีประสิทธิภาพ
**คำเตือน:** การใช้คำสั่ง Git บางคำสั่งอาจจะทำให้ข้อมูลสูญหายได้ ดังนั้นควร Backup ข้อมูลก่อนที่จะทำการแก้ไขอะไรที่สำคัญๆ เสมอ
* **การแก้ไข Commit Message:** บางครั้งเราอาจจะ Commit ไปแล้วเพิ่งนึกได้ว่า Commit Message ที่เขียนไปนั้นไม่ถูกต้อง หรือมีข้อมูลที่ต้องการแก้ไข เราสามารถแก้ไข Commit Message ล่าสุดได้โดยใช้คำสั่ง
git commit --amend -m "Commit Message ใหม่"
    
คำสั่งนี้จะทำการแก้ไข Commit Message ล่าสุดให้เป็น "Commit Message ใหม่" ถ้าเราต้องการแก้ไข Commit Message ที่เก่ากว่านั้น เราจะต้องใช้คำสั่ง `git rebase -i` ซึ่งจะมีความซับซ้อนกว่า * **การยกเลิก Commit:** ถ้าเรา Commit ไปแล้ว แต่เพิ่งนึกได้ว่าเรายังไม่ได้ Add ไฟล์บางไฟล์ หรือมี Code ที่ต้องการแก้ไข เราสามารถยกเลิก Commit ล่าสุดได้โดยใช้คำสั่ง
git reset --soft HEAD^
    
คำสั่งนี้จะทำการยกเลิก Commit ล่าสุด แต่จะยังคงเก็บไฟล์ที่เรา Commit ไว้ใน Staging Area เราสามารถแก้ไขไฟล์และ Commit ใหม่อีกครั้งได้ * **การแก้ไข Branch ที่ผิดพลาด:** บางครั้งเราอาจจะสร้าง Branch ผิด หรือ Commit ไปใน Branch ที่ไม่ถูกต้อง เราสามารถแก้ไขได้โดยการ Checkout ไปยัง Branch ที่ถูกต้อง และทำการ Merge Branch ที่ผิดพลาดเข้ามา หรือถ้าเรายังไม่ได้ Push Branch ที่ผิดพลาดขึ้นไป เราสามารถ Reset Branch นั้นกลับไปยัง Commit ก่อนหน้าได้ * **การแก้ไข Conflict ในการ Merge:** Conflict เป็นสิ่งที่หลีกเลี่ยงไม่ได้ในการทำงานร่วมกับคนอื่นๆ ในทีม เมื่อเกิด Conflict เราจะต้องแก้ไข Conflict ในไฟล์ที่เกิด Conflict ก่อนที่จะทำการ Commit การแก้ไข Conflict สามารถทำได้โดยการเปิดไฟล์ที่เกิด Conflict และแก้ไข Code ให้ถูกต้อง จากนั้นทำการ Add และ Commit ไฟล์นั้น การแก้ไข Conflict อาจจะเป็นเรื่องที่น่าปวดหัว แต่ถ้าเราเข้าใจวิธีการแก้ไข Conflict และมีเครื่องมือที่ช่วยในการแก้ไข Conflict ก็จะทำให้การทำงานง่ายขึ้น * **การกู้คืนไฟล์ที่ถูกลบ:** ถ้าเราเผลอลบไฟล์ใน Git Repository เราสามารถกู้คืนไฟล์นั้นได้โดยใช้คำสั่ง
git checkout -- ชื่อไฟล์
    
คำสั่งนี้จะทำการกู้คืนไฟล์จาก Commit ล่าสุด ถ้าเราต้องการกู้คืนไฟล์จาก Commit ที่เก่ากว่านั้น เราจะต้องใช้คำสั่ง `git log` เพื่อหา Commit ที่มีไฟล์นั้นอยู่ และใช้คำสั่ง `git checkout CommitID -- ชื่อไฟล์` เพื่อกู้คืนไฟล์จาก Commit นั้น

ตัวอย่างจากประสบการณ์ 20 ปี

ตลอด 20 ปีที่ผมคลุกคลีอยู่ในวงการ IT ผมได้เจอปัญหาและความท้าทายต่างๆ มากมายในการใช้ Git ในการทำงานจริง ผมอยากจะแชร์ประสบการณ์บางส่วนที่ผมได้เจอมา เพื่อเป็นแนวทางให้กับทุกคนที่กำลังเริ่มต้นใช้งาน Git หรือกำลังเจอปัญหาในการใช้งาน Git * **การจัดการ Hotfix:** ในโปรเจกต์ขนาดใหญ่ มักจะมี Hotfix ที่ต้องแก้ไข Bug ด่วนใน Production Environment ผมเคยเจอปัญหาที่ทีมงาน Commit Hotfix เข้าไปใน `master` Branch โดยตรง ซึ่งทำให้เกิดปัญหาในการ Merge กับ `develop` Branch ในภายหลัง สิ่งที่ถูกต้องคือเราควรสร้าง Hotfix Branch แยกออกมาจาก `master` Branch ทำการแก้ไข Bug ใน Hotfix Branch และ Merge Hotfix Branch กลับไปทั้ง `master` และ `develop` Branch การทำแบบนี้จะช่วยให้เราสามารถจัดการ Hotfix ได้อย่างเป็นระบบ และป้องกันไม่ให้เกิดปัญหาในการ Merge ในภายหลัง * **การใช้ Gitflow Workflow:** Gitflow เป็น Workflow ที่ได้รับความนิยมในการจัดการ Branch ในโปรเจกต์ขนาดใหญ่ Gitflow กำหนดให้เรามี Branch หลัก 2 Branch คือ `master` และ `develop` และ Branch รองอีกหลาย Branch เช่น `feature`, `release` และ `hotfix` ผมเคยใช้ Gitflow ในโปรเจกต์ขนาดใหญ่ และพบว่ามันช่วยให้ทีมงานสามารถทำงานร่วมกันได้อย่างมีประสิทธิภาพ และลดปัญหาในการ Merge อย่างไรก็ตาม Gitflow ก็มีความซับซ้อนพอสมควร ดังนั้นควรศึกษาและทำความเข้าใจ Gitflow ให้ดีก่อนที่จะนำไปใช้ในโปรเจกต์จริง * **การจัดการ Secret Keys:** การเก็บ Secret Keys (เช่น API Keys, Database Passwords) ไว้ใน Git Repository เป็นเรื่องที่อันตรายมาก เพราะถ้ามีใครเข้าถึง Repository ของเราได้ ก็จะสามารถเข้าถึง Secret Keys เหล่านั้นได้ ผมเคยเจอปัญหาที่ทีมงาน Commit Secret Keys เข้าไปใน Repository โดยไม่ได้ตั้งใจ วิธีแก้ไขคือเราจะต้องลบ Secret Keys ออกจาก Repository และเปลี่ยน Secret Keys ใหม่ นอกจากนี้เราควรใช้เครื่องมือที่ช่วยในการจัดการ Secret Keys เช่น HashiCorp Vault หรือ AWS Secrets Manager เพื่อป้องกันไม่ให้เกิดปัญหาแบบนี้อีก ตรงนี้สำคัญมากนะ! เพราะถ้า Secret Keys หลุดออกไป อาจจะทำให้เกิดความเสียหายอย่างมากต่อธุรกิจของเราได้ * **การใช้ Submodule:** Git Submodule เป็นเครื่องมือที่ช่วยให้เราสามารถ Include Git Repository อื่นๆ เข้ามาใน Git Repository ของเราได้ ผมเคยใช้ Submodule ในการ Include Library ที่พัฒนาโดยทีมอื่น เข้ามาในโปรเจกต์ของเรา ปัญหาที่ผมเจอคือการ Update Submodule ให้เป็นเวอร์ชันล่าสุด ซึ่งจะต้องใช้คำสั่ง `git submodule update --init --recursive` ทุกครั้งที่มีการเปลี่ยนแปลงใน Submodule นอกจากนี้การจัดการ Submodule ก็มีความซับซ้อนพอสมควร ดังนั้นควรศึกษาและทำความเข้าใจ Submodule ให้ดีก่อนที่จะนำไปใช้ในโปรเจกต์จริง ใครเคยเจอบ้าง? เรื่อง Submodule นี่เป็นอะไรที่ปวดหัวมากจริงๆ * **การแก้ไข Branch ที่ Remote:** บางครั้งเราอาจจะต้องแก้ไข Branch ที่ Remote Repository เช่น การ Revert Commit หรือการ Reset Branch กลับไปยัง Commit ก่อนหน้า การแก้ไข Branch ที่ Remote จะต้องใช้คำสั่ง `git push --force` ซึ่งเป็นคำสั่งที่อันตรายมาก เพราะมันจะ Overwrite Branch ที่ Remote ด้วย Branch ใน Local ของเรา ดังนั้นควรใช้คำสั่งนี้ด้วยความระมัดระวัง และควรแจ้งให้ทีมงานทราบก่อนที่จะทำการแก้ไข Branch ที่ Remote สมัยก่อนผมก็เคยพลาดใช้ `git push --force` โดยไม่ได้แจ้งให้ทีมงานทราบ ทำให้เกิดปัญหาในการทำงานร่วมกัน ดังนั้นควรระมัดระวังในการใช้คำสั่งนี้ให้มาก

เครื่องมือแนะนำสำหรับ Git

การทำงานกับ Git ไม่ได้จำกัดอยู่แค่ Command Line Interface (CLI) อย่างเดียวนะครับ จริงๆ แล้วมีเครื่องมือมากมายที่ช่วยให้เราทำงานกับ Git ได้ง่ายขึ้น สะดวกขึ้น และมีประสิทธิภาพมากขึ้น ไม่ว่าจะเป็น GUI clients ที่ช่วยให้เห็นภาพรวมของ repository ได้ชัดเจน หรือจะเป็น plugins สำหรับ IDE ที่ช่วยให้เรา commit, push, pull ได้โดยไม่ต้องออกจาก editor เลย

Git GUI Clients: ทางเลือกสำหรับคนไม่ถนัด Command Line

สำหรับใครที่ไม่ถนัดการพิมพ์คำสั่งยาวๆ หรืออยากเห็นภาพรวมของ repository แบบเข้าใจง่าย Git GUI clients คือทางเลือกที่น่าสนใจมากครับ โปรแกรมเหล่านี้มักจะมี interface ที่ใช้งานง่าย ช่วยให้เราจัดการ branch, commit, merge ได้อย่างสะดวกสบาย แถมยังแสดง history ของไฟล์ต่างๆ ได้อย่างชัดเจนอีกด้วย ตัวอย่าง Git GUI clients ที่ได้รับความนิยม: * **GitKraken:** ตัวนี้สวยงาม ใช้งานง่าย มี feature ครบครัน แต่ต้องเสียเงินถ้าใช้ในเชิง commercial * **SourceTree:** ฟรี ใช้งานได้ทั้ง Windows และ macOS เหมาะสำหรับคนที่ต้องการ client ที่เรียบง่ายแต่ทรงพลัง * **GitHub Desktop:** จาก GitHub โดยตรง เน้นการทำงานร่วมกับ GitHub repository เป็นหลัก ใช้งานง่าย เหมาะสำหรับมือใหม่ ผมเคยใช้ GitKraken ตอนเริ่มทำงานใหม่ๆ เพราะ interface มันสวยดีครับ (ยอมรับเลยว่าเหตุผลหลักคือเรื่องนี้แหละ) แต่พอใช้ไปนานๆ ก็เริ่มรู้สึกว่ามันหนักเครื่องไปหน่อย เลยเปลี่ยนมาใช้ SourceTree แทน ซึ่งก็ตอบโจทย์ผมได้ดีกว่า

Git IDE Plugins: ทำทุกอย่างได้ใน Editor ตัวโปรด

ถ้าคุณเป็นคนที่ใช้ IDE เป็นหลักในการเขียนโปรแกรม Git IDE plugins จะช่วยให้ชีวิตง่ายขึ้นเยอะเลยครับ Plugin เหล่านี้จะ integrate Git เข้าไปใน IDE ของคุณ ทำให้คุณสามารถ commit, push, pull, branch ได้โดยไม่ต้องสลับหน้าจอไปมา แถมยังช่วย highlight changes ในไฟล์ และแสดง diff ได้อย่างสะดวกอีกด้วย ตัวอย่าง Git IDE plugins ที่น่าสนใจ: * **GitLens (Visual Studio Code):** สุดยอด plugin สำหรับ VS Code ที่ช่วยให้คุณเห็น history ของแต่ละบรรทัดในไฟล์, blame, code authorship และอื่นๆ อีกมากมาย * **Git Integration (IntelliJ IDEA):** IntelliJ IDEA มี Git integration มาให้ในตัวอยู่แล้ว แต่ plugin นี้จะช่วยเพิ่ม feature และปรับแต่งการทำงานให้ดียิ่งขึ้น * **EGit (Eclipse):** สำหรับคนที่ยังใช้ Eclipse อยู่ EGit คือ plugin ที่ขาดไม่ได้ ช่วยให้คุณทำงานกับ Git ได้อย่างราบรื่น สมัยก่อนผมใช้ Eclipse แล้วก็ต้องลง EGit ตลอด เพราะมันช่วยให้ชีวิตง่ายขึ้นเยอะมากครับ แต่พอเปลี่ยนมาใช้ VS Code ก็ติดใจ GitLens เลย เพราะมันแสดง history ของแต่ละบรรทัดได้ละเอียดมากๆ

Git Command Line Tools เสริม: เพิ่มความสามารถให้ Command Line

ถึงแม้ว่า Command Line จะดูยากสำหรับบางคน แต่จริงๆ แล้วมันทรงพลังมากๆ นะครับ และยังมี tools เสริมอีกมากมายที่ช่วยเพิ่มความสามารถให้กับ Git command line ทำให้เราทำงานได้รวดเร็วและมีประสิทธิภาพมากขึ้น ตัวอย่าง Git command line tools เสริม: * **tig:** Text-mode interface สำหรับ Git ช่วยให้คุณ browse repository history ได้อย่างรวดเร็ว * **delta:** ช่วยให้ diff อ่านง่ายขึ้น โดยการ highlight changes ในระดับคำ (word-level) แทนที่จะเป็นแค่ระดับบรรทัด * **git-extras:** รวมคำสั่ง Git เพิ่มเติมที่เป็นประโยชน์ เช่น `git obliterate` (ลบไฟล์ออกจาก history อย่างถาวร) หรือ `git effort` (แสดงสถิติการ commit ตามเวลา) ผมชอบใช้ `tig` มากครับ เพราะมันช่วยให้ผม browse history ได้เร็วกว่า `git log` เยอะเลย แถมยังแสดง diff ได้สวยงามอีกด้วย

Case Study: ประสบการณ์จริงกับการใช้ Git ในโปรเจกต์ขนาดใหญ่

ผมเคยร่วมทีมพัฒนาโปรเจกต์ขนาดใหญ่ที่ใช้ Git เป็น version control system หลักครับ โปรเจกต์นี้มี codebase ขนาดใหญ่ มีทีมพัฒนาหลายสิบคน และมีการเปลี่ยนแปลง code อยู่ตลอดเวลา การใช้ Git อย่างมีประสิทธิภาพจึงเป็นสิ่งสำคัญมาก **ปัญหาที่เจอ:** * **Conflict บ่อย:** เนื่องจากมีคนแก้ไขไฟล์เดียวกันเยอะ ทำให้เกิด conflict บ่อยมาก เสียเวลาแก้ conflict ไปเยอะ * **Branch เยอะ:** มี branch เยอะมาก ทั้ง feature branch, release branch, hotfix branch ทำให้สับสนว่า branch ไหนคือ branch ไหน * **Code review ช้า:** Code review ใช้เวลานาน เพราะต้องอ่าน code ที่เปลี่ยนแปลงเยอะมาก **วิธีแก้ไข:** * **Feature branches สั้นๆ:** เราพยายามทำให้ feature branches มีขนาดเล็ก และ merge เข้า `main` ให้เร็วที่สุด เพื่อลดโอกาสเกิด conflict * **Git flow:** เราใช้ Git flow เป็น branching model เพื่อจัดการ branches ต่างๆ ให้เป็นระบบ * **Code review อย่างสม่ำเสมอ:** เรากำหนดให้ทุกคนต้อง review code อย่างน้อยวันละครั้ง เพื่อให้ code review เสร็จเร็วขึ้น * **เครื่องมือช่วย:** เราใช้เครื่องมือช่วยในการ merge และ resolve conflict เช่น `git mergetool` และ `diff3` **ผลลัพธ์:** * **Conflict ลดลง 50%:** การทำ feature branches สั้นๆ ช่วยลด conflict ได้อย่างมีนัยสำคัญ * **Code review เร็วขึ้น 30%:** การ review code อย่างสม่ำเสมอ ช่วยให้ code review เสร็จเร็วขึ้น และลดจำนวน bug ที่เกิดขึ้น * **คุณภาพ code ดีขึ้น:** การ review code อย่างละเอียด ช่วยให้เราเจอ bug และปรับปรุง code ให้ดีขึ้น **ตัวเลขจริง:** * **จำนวน commit ต่อวัน:** เฉลี่ย 50-100 commits * **จำนวน branches:** เฉลี่ย 20-30 branches * **ขนาด codebase:** ประมาณ 500,000 lines of code **สิ่งที่ได้เรียนรู้:** * **การสื่อสารสำคัญ:** การสื่อสารที่ดีระหว่างทีมพัฒนาเป็นสิ่งสำคัญมาก เพื่อให้ทุกคนเข้าใจว่าใครกำลังทำอะไร และช่วยลดโอกาสเกิด conflict * **Git flow ช่วยได้:** Git flow เป็น branching model ที่มีประโยชน์มาก แต่ต้องปรับให้เข้ากับ workflow ของทีม * **เครื่องมือช่วยได้:** เครื่องมือช่วยในการ merge และ resolve conflict ช่วยประหยัดเวลาได้เยอะ

FAQ: คำถามที่พบบ่อยเกี่ยวกับ Git

Git นี่มีอะไรให้เรียนรู้อีกเยอะเลยนะครับ และก็มีคำถามที่มือใหม่มักจะถามกันบ่อยๆ ผมเลยรวบรวมคำถามที่พบบ่อยมาตอบให้ เผื่อว่าใครที่กำลังเริ่มต้นจะได้เข้าใจ Git ได้ง่ายขึ้น

Q: จะยกเลิก commit ล่าสุดได้อย่างไร?

A: ถ้าคุณ commit ไปแล้ว แต่เพิ่งนึกขึ้นได้ว่าลืมใส่ไฟล์บางไฟล์ หรือมีข้อผิดพลาดเล็กน้อย คุณสามารถยกเลิก commit ล่าสุดได้ด้วยคำสั่ง `git reset --soft HEAD~1` คำสั่งนี้จะยกเลิก commit ล่าสุด แต่จะเก็บ changes ที่คุณทำไว้ใน working directory ทำให้คุณสามารถแก้ไข changes แล้ว commit ใหม่ได้
git reset --soft HEAD~1
ถ้าคุณต้องการทิ้ง changes ที่ทำไว้ด้วย ให้ใช้ `--hard` แทน แต่ต้องระวัง เพราะ changes ที่ทิ้งไปแล้วจะกู้คืนได้ยาก

Q: จะ revert commit ที่ commit ไปนานแล้วได้อย่างไร?

A: ถ้าคุณต้องการยกเลิก commit ที่ commit ไปนานแล้ว คุณสามารถใช้คำสั่ง `git revert ` คำสั่งนี้จะสร้าง commit ใหม่ที่ยกเลิก changes ที่เกิดจาก commit ที่ระบุ
git revert 
การ revert commit จะไม่เปลี่ยนแปลง history ของ repository แต่จะเพิ่ม commit ใหม่เข้าไป ทำให้ง่ายต่อการติดตามการเปลี่ยนแปลง

Q: จะแก้ไข commit message ล่าสุดได้อย่างไร?

A: ถ้าคุณพิมพ์ commit message ผิด หรือลืมใส่รายละเอียดบางอย่าง คุณสามารถแก้ไข commit message ล่าสุดได้ด้วยคำสั่ง `git commit --amend` คำสั่งนี้จะเปิด editor ให้คุณแก้ไข commit message
git commit --amend
ถ้าคุณต้องการแก้ไข commit message ของ commit ที่ commit ไปนานแล้ว คุณจะต้องใช้ `git rebase -i` ซึ่งซับซ้อนกว่า

Q: จะจัดการกับ conflict ตอน merge อย่างไร?

A: Conflict เกิดขึ้นเมื่อมีการเปลี่ยนแปลง code ในส่วนเดียวกันในสอง branches ที่แตกต่างกัน เมื่อเกิด conflict Git จะแจ้งให้คุณทราบ และคุณจะต้องแก้ไข conflict ด้วยตัวเอง โดยการเปิดไฟล์ที่มี conflict แล้วแก้ไข code ให้ถูกต้อง จากนั้นให้ใช้ `git add` เพื่อ mark ว่าไฟล์นั้นได้รับการแก้ไขแล้ว และใช้ `git commit` เพื่อ commit changes
git add 
git commit
การแก้ไข conflict อาจจะยาก แต่เป็นส่วนหนึ่งของการทำงานร่วมกันในทีม

Q: จะ undo `git add` ได้อย่างไร?

A: ถ้าคุณเผลอ `git add` ไฟล์ที่ไม่ต้องการ คุณสามารถ undo ได้ด้วยคำสั่ง `git reset HEAD ` คำสั่งนี้จะนำไฟล์ออกจาก staging area แต่จะยังคงไฟล์ไว้ใน working directory
git reset HEAD 
ถ้าคุณต้องการนำไฟล์ทั้งหมดออกจาก staging area ให้ใช้ `git reset HEAD` โดยไม่ระบุชื่อไฟล์

Q: จะ clone repository เฉพาะ branch ที่ต้องการได้อย่างไร?

A: ปกติแล้ว `git clone` จะ clone ทุก branch ใน repository แต่ถ้าคุณต้องการ clone เฉพาะ branch ที่ต้องการ คุณสามารถใช้ option `--single-branch` และ `--branch`
git clone --single-branch --branch  
วิธีนี้จะช่วยประหยัดเวลาและ bandwidth โดยเฉพาะอย่างยิ่งสำหรับ repository ขนาดใหญ่

สรุป: Git ไม่ยากอย่างที่คิด

Git อาจจะดูน่ากลัวสำหรับมือใหม่ แต่จริงๆ แล้วมันเป็นเครื่องมือที่ทรงพลังและจำเป็นสำหรับการพัฒนา software ในยุคปัจจุบัน การเข้าใจ Git จะช่วยให้คุณทำงานร่วมกับคนอื่นได้อย่างมีประสิทธิภาพ จัดการ code ได้อย่างเป็นระบบ และลดความเสี่ยงในการสูญเสียข้อมูล สิ่งที่สำคัญที่สุดในการเรียนรู้ Git คือการลงมือทำ ลองสร้าง repository เล่นๆ ลอง commit, branch, merge, pull, push ดู แล้วคุณจะเริ่มเข้าใจ Git มากขึ้นเรื่อยๆ อย่ากลัวที่จะลองผิดลองถูก เพราะการผิดพลาดคือส่วนหนึ่งของการเรียนรู้ ผมอยากแนะนำให้คุณเริ่มจากการเรียนรู้คำสั่งพื้นฐานที่กล่าวมาทั้งหมดในบทความนี้ก่อน จากนั้นค่อยๆ ศึกษาคำสั่งอื่นๆ เพิ่มเติมตามความจำเป็น และอย่าลืมใช้เครื่องมือช่วยต่างๆ ที่มีอยู่มากมาย เพื่อให้การทำงานกับ Git ง่ายขึ้น Git ไม่ใช่เรื่องยากอย่างที่คิด ขอแค่คุณเปิดใจเรียนรู้และฝึกฝนอย่างสม่ำเสมอ ผมเชื่อว่าคุณจะสามารถใช้ Git ได้อย่างคล่องแคล่วแน่นอนครับ ขอให้สนุกกับการเรียนรู้ Git นะครับ!

Tips จากประสบการณ์ 20 ปี

1. Commit message ที่ดี ชีวิตดี๊ดี

Commit message เหมือนเป็นบันทึกการเดินทางของโปรเจกต์เราครับ ลองคิดดูว่าถ้าเรากลับมาดูโค้ดที่เขียนไว้เมื่อ 6 เดือนที่แล้ว แล้ว commit message เป็นแค่ "แก้ไข" หรือ "อัพเดท" เราจะรู้เรื่องไหมเนี่ย? ผมเคยเจอปัญหาแบบนี้บ่อยมาก สมัยก่อนก็ไม่ได้ใส่ใจเรื่องนี้เท่าไหร่ แต่พอโปรเจกต์มันใหญ่ขึ้นเรื่อยๆ Commit message ที่ดีจะช่วยให้เราเข้าใจ history ของโค้ดได้ง่ายขึ้นมากๆ

หลักการง่ายๆ คือ commit message ควรจะสั้น กระชับ และสื่อความหมายครับ บรรทัดแรกควรสรุปว่า commit นี้ทำอะไร (ไม่เกิน 50 ตัวอักษร) แล้วถ้ามีรายละเอียดเพิ่มเติมก็ค่อยใส่ใน body ครับ พยายามเขียนให้ชัดเจนว่าเราแก้ไขอะไร ทำไมถึงแก้ไข และมีผลกระทบอะไรบ้าง ถ้าทำตามนี้ได้ ชีวิตจะง่ายขึ้นเยอะเลยครับ

ตัวอย่าง commit message ที่ดี:

feat: Add user authentication

This commit introduces user authentication using JWT.

- Implemented login and registration endpoints.
- Added middleware to protect routes.
- Updated database schema to store user credentials.

Commit message ที่ดีช่วยให้คนอื่น (รวมถึงตัวเราเองในอนาคต) เข้าใจการเปลี่ยนแปลงของโค้ดได้ง่ายขึ้น ทำให้การทำงานร่วมกันเป็นทีมมีประสิทธิภาพมากขึ้น และช่วยให้การ debug ง่ายขึ้นด้วยครับ ตรงนี้สำคัญมากนะ!

2. Branching Strategy ที่ใช่ ช่วยให้รอด

Branching strategy คือวิธีการที่เราจัดการ branch ใน Git ครับ มีหลายแบบให้เลือกใช้ เช่น Gitflow, GitHub Flow, GitLab Flow แต่ละแบบก็มีข้อดีข้อเสียต่างกันไป ขึ้นอยู่กับขนาดของโปรเจกต์และทีมงาน ผมเคยเซ็ตตอนปี 2020 ใช้ Gitflow แล้วปวดหัวมาก เพราะมันซับซ้อนเกินไปสำหรับทีมเล็กๆ สุดท้ายก็ต้องเปลี่ยนมาใช้ GitHub Flow แทน

Branching strategy ที่ดีจะช่วยให้เราทำงานร่วมกันได้ง่ายขึ้น ลดความเสี่ยงในการ merge code ที่ไม่สมบูรณ์ และช่วยให้เราจัดการ release ได้ง่ายขึ้นด้วย หลักการง่ายๆ คือ เลือก strategy ที่เหมาะสมกับขนาดของทีมและความซับซ้อนของโปรเจกต์ แล้วก็พยายามทำให้มันง่ายที่สุดเท่าที่จะทำได้ครับ

ตัวอย่าง GitHub Flow:

  1. สร้าง branch ใหม่จาก `main` สำหรับแต่ละ feature หรือ bug fix
  2. Commit code ไปที่ branch นั้น
  3. สร้าง pull request เพื่อ merge branch นั้นเข้ากับ `main`
  4. Review code
  5. Merge pull request
  6. Deploy `main`

การเลือก Branching Strategy ที่เหมาะสม เป็นสิ่งสำคัญมากๆ ครับ เพราะมันส่งผลต่อ workflow ของทีมโดยตรง ถ้าเลือกผิด ชีวิตจะวุ่นวายแน่นอน!

3. .gitignore file คือเพื่อนแท้

.gitignore file คือไฟล์ที่บอก Git ว่าไฟล์หรือ directory ไหนที่เราไม่อยากให้ Git track ครับ พวกไฟล์ temporary, ไฟล์ config ที่มีข้อมูล sensitive, หรือพวก build artifact ต่างๆ เราควรใส่ไว้ใน .gitignore file ให้หมด

ผมเคยพลาดตอนที่ไม่ได้ใส่ `.env` file (ที่มี API key) ไว้ใน .gitignore แล้ว commit ขึ้นไปบน GitHub ผลคือ API key หลุด แล้วโดนเอาไปใช้จนบิลค่าบริการพุ่งกระฉูด! ตั้งแต่นั้นมา ผมก็เลยระวังเรื่องนี้มากๆ

ตัวอย่าง .gitignore file:

node_modules/
.env
*.log
build/
dist/

การใช้ .gitignore file อย่างถูกต้องจะช่วยให้ repository เราสะอาดขึ้น ลดขนาดของ repository และป้องกันไม่ให้เรา commit ไฟล์ที่ไม่จำเป็นขึ้นไปครับ ใครยังไม่เคยใช้ ลองใช้ดูนะ แล้วจะติดใจ!

4. Staging Area: ก่อน Commit คิดดีๆ

Staging area คือพื้นที่ที่เราเอาไฟล์ที่เราต้องการ commit ไปพักไว้ก่อนครับ ก่อนที่จะ commit จริงๆ เราควรตรวจสอบ staging area ให้ดี ว่ามีไฟล์อะไรที่เราไม่ได้ตั้งใจจะ commit ติดไปด้วยหรือเปล่า

ผมเคย commit ไฟล์ `.DS_Store` (ไฟล์ของ macOS) ขึ้นไปบน repository โดยไม่ได้ตั้งใจ ทำให้ repository ดูรกๆ ไม่สวยงาม ตั้งแต่นั้นมา ผมก็เลยต้องเช็ค staging area ทุกครั้งก่อน commit

Command ที่ใช้บ่อยๆ เกี่ยวกับ staging area:

  • git add .: เพิ่มไฟล์ทั้งหมดใน working directory ไปที่ staging area
  • git add <file>: เพิ่มไฟล์ที่ระบุไปที่ staging area
  • git status: แสดงสถานะของ working directory และ staging area
  • git reset HEAD <file>: เอาไฟล์ที่ระบุออกจาก staging area

การใช้ Staging area อย่างระมัดระวัง จะช่วยให้ Commit ของเราสะอาดและตรงตามที่เราต้องการครับ

5. Rebase vs. Merge: เลือกให้ถูก

Rebase และ Merge เป็นสองวิธีหลักในการรวม branch เข้าด้วยกันครับ แต่ทั้งสองวิธีมีวิธีการทำงานที่แตกต่างกัน และส่งผลต่อ history ของ Git ที่แตกต่างกันด้วย

Merge จะสร้าง commit ใหม่ที่รวมการเปลี่ยนแปลงจากสอง branch เข้าด้วยกัน ทำให้ history ของ Git ดูเป็นกราฟที่มีกิ่งก้านสาขาเยอะแยะไปหมด ส่วน Rebase จะเอา commit ของ branch นึงไปต่อท้าย branch อีก branch นึง ทำให้ history ของ Git ดูเป็นเส้นตรง

โดยทั่วไปแล้ว Rebase จะเหมาะกับการรวม branch feature เข้ากับ branch หลัก (เช่น `main`) เพราะจะทำให้ history ของ Git สะอาดและอ่านง่าย แต่ต้องระวัง เพราะ Rebase จะเปลี่ยน history ของ commit ดังนั้นไม่ควร Rebase branch ที่มีคนอื่นใช้งานอยู่

ส่วน Merge จะเหมาะกับการรวม branch หลักเข้ากับ branch feature หรือกับการรวม branch ที่มีคนอื่นใช้งานอยู่

Command ที่ใช้บ่อยๆ เกี่ยวกับ Rebase และ Merge:

git rebase <branch>
git merge <branch>

การเลือกว่าจะใช้ Rebase หรือ Merge ขึ้นอยู่กับสถานการณ์และความชอบส่วนบุคคล แต่สิ่งสำคัญคือต้องเข้าใจความแตกต่างของทั้งสองวิธี และเลือกวิธีที่เหมาะสมกับสถานการณ์นั้นๆ ครับ

6. Interactive Staging: ละเอียดทุกเม็ด

Interactive staging (ใช้ `git add -p`) เป็นเครื่องมือที่ช่วยให้เราเลือกเฉพาะส่วนของไฟล์ที่เราต้องการ commit ได้ เหมาะสำหรับกรณีที่เราแก้ไขไฟล์เยอะมาก แต่เราต้องการแบ่งการเปลี่ยนแปลงออกเป็น commit เล็กๆ หลายๆ commit

ผมเคยใช้ interactive staging ตอนที่แก้ไข bug ใหญ่ในโปรเจกต์นึง แล้วผมแก้ไขไฟล์ไปหลายที่มาก ถ้าผม commit ทุกอย่างพร้อมกัน commit message ก็จะยาวเหยียดและอ่านยาก ผมเลยใช้ interactive staging เพื่อแบ่งการเปลี่ยนแปลงออกเป็น commit เล็กๆ หลายๆ commit แต่ละ commit ก็จะ focus ที่การแก้ไข bug ในส่วนๆ เดียว

การใช้ interactive staging อาจจะดูยุ่งยากในตอนแรก แต่พอใช้คล่องแล้ว จะช่วยให้เราจัดการ commit ได้ละเอียดมากขึ้น และทำให้ history ของ Git สะอาดและอ่านง่ายขึ้นครับ

ลองใช้ git add -p แล้วจะรู้ว่ามันมีประโยชน์มากแค่ไหน!

7. Cherry-picking: เลือกสิ่งที่ดีที่สุด

Cherry-picking คือการเลือก commit บาง commit จาก branch นึง ไปใส่ในอีก branch นึง เหมาะสำหรับกรณีที่เราต้องการเอาเฉพาะการแก้ไขบางอย่างจาก branch นึงไปใช้ในอีก branch นึง โดยที่ไม่ต้องการรวม branch ทั้งหมด

ผมเคยใช้ cherry-picking ตอนที่ผมแก้ไข bug ใน branch `develop` แล้วผมต้องการเอาการแก้ไขนั้นไปใส่ใน branch `hotfix` เพื่อ deploy ขึ้น production โดยที่ไม่ต้องการรวม branch `develop` ทั้งหมด เพราะมันยังไม่เสร็จ

Command ที่ใช้ในการ cherry-picking:

git cherry-pick <commit-hash>

การใช้ cherry-picking ต้องระวังเรื่อง conflict ด้วย เพราะ commit ที่เราเลือกมาอาจจะขัดแย้งกับ code ใน branch ที่เราจะเอาไปใส่ ดังนั้นเราอาจจะต้องแก้ไข conflict ก่อนที่จะ commit

Cherry-picking เป็นเครื่องมือที่มีประโยชน์มาก แต่ต้องใช้ด้วยความระมัดระวังครับ

8. Git Hooks: ผู้ช่วยอัตโนมัติ

Git hooks คือ script ที่ Git จะรันโดยอัตโนมัติเมื่อมี event บางอย่างเกิดขึ้น เช่น ก่อน commit, หลัง commit, ก่อน push, หลัง push เราสามารถใช้ Git hooks เพื่อตรวจสอบ code quality, รัน test, หรือทำอย่างอื่นที่เราต้องการได้

ผมเคยใช้ Git hooks เพื่อตรวจสอบ commit message ก่อนที่จะอนุญาตให้ commit ได้ ถ้า commit message ไม่เป็นไปตาม format ที่กำหนด Git ก็จะ reject commit นั้น ทำให้ commit message ในโปรเจกต์เป็นไปในทิศทางเดียวกัน

Git hooks จะอยู่ใน directory `.git/hooks` ใน repository ของเรา เราสามารถเขียน script ในภาษาอะไรก็ได้ (เช่น bash, python, ruby) แล้วตั้งชื่อไฟล์ให้ตรงกับชื่อ hook ที่เราต้องการ (เช่น `pre-commit`, `post-commit`, `pre-push`, `post-push`) แล้ว Git ก็จะรัน script นั้นโดยอัตโนมัติ

Git hooks เป็นเครื่องมือที่ทรงพลังมาก แต่ต้องใช้ด้วยความระมัดระวัง เพราะ script ที่เราเขียนอาจจะทำให้ Git ทำงานช้าลง หรืออาจจะทำให้ Git ทำงานผิดพลาดได้

FAQ เพิ่ม 4 ข้อ

H3: Conflict เกิดจากอะไร และมีวิธีแก้อย่างไร?

Conflict เกิดขึ้นเมื่อ Git ไม่สามารถรวมการเปลี่ยนแปลงจากสอง branch เข้าด้วยกันได้โดยอัตโนมัติ สาเหตุส่วนใหญ่คือมีการแก้ไขไฟล์เดียวกันในสอง branch ที่แตกต่างกัน และ Git ไม่รู้ว่าจะเลือกการแก้ไขแบบไหน

วิธีแก้ conflict คือเราต้องเปิดไฟล์ที่มี conflict แล้วแก้ไขด้วยตัวเอง โดย Git จะใส่เครื่องหมายพิเศษ (เช่น <<<<<<<, =======, >>>>>>>>>) เพื่อบอกเราว่าส่วนไหนของไฟล์ที่มี conflict เราต้องอ่าน code ทั้งสองฝั่ง แล้วตัดสินใจว่าจะเลือก code แบบไหน หรือจะแก้ไข code ใหม่ให้รวมทั้งสองแบบเข้าด้วยกัน

หลังจากแก้ไข conflict เสร็จแล้ว เราก็ต้องเอาเครื่องหมายพิเศษเหล่านั้นออก แล้ว add ไฟล์นั้นไปที่ staging area แล้ว commit

git add <file>
git commit -m "Resolve conflict"

การแก้ conflict อาจจะดูน่ากลัวในตอนแรก แต่ถ้าเราเข้าใจว่า conflict เกิดจากอะไร และรู้วิธีแก้ไข มันก็ไม่ได้ยากอย่างที่คิดครับ

H3: Detached HEAD คืออะไร และจะกลับไป branch เดิมได้อย่างไร?

Detached HEAD คือสถานะที่ HEAD (pointer ที่ชี้ไปยัง commit ปัจจุบัน) ไม่ได้ชี้ไปยัง branch ใดๆ สถานะนี้มักจะเกิดขึ้นเมื่อเรา checkout ไปยัง commit hash โดยตรง แทนที่จะ checkout ไปยัง branch

ถ้าเราอยู่ในสถานะ Detached HEAD แล้วเรา commit การเปลี่ยนแปลง Git จะสร้าง commit ใหม่ แต่ commit นั้นจะไม่ได้อยู่ใน branch ใดๆ ถ้าเรา checkout กลับไปยัง branch อื่น commit นั้นก็จะหายไป (จริงๆ คือไม่ได้หายไปไหน แต่เราเข้าถึงมันไม่ได้)

วิธีกลับไป branch เดิมคือเราต้อง checkout กลับไปยัง branch นั้น:

git checkout <branch>

ถ้าเราต้องการเก็บ commit ที่เราสร้างไว้ในสถานะ Detached HEAD เราสามารถสร้าง branch ใหม่จาก commit นั้นได้:

git checkout -b <new-branch>

แล้วค่อย merge branch ใหม่นี้เข้ากับ branch เดิม หรือ cherry-pick commit นั้นไปใส่ใน branch เดิม

H3: Submodule กับ Subtree ต่างกันอย่างไร?

Submodule และ Subtree เป็นสองวิธีในการรวม repository Git นึงไว้ในอีก repository นึง แต่ทั้งสองวิธีมีวิธีการทำงานที่แตกต่างกัน

Submodule จะสร้าง pointer ไปยัง commit ที่ระบุใน repository อื่น ทำให้ repository หลักไม่ได้เก็บ code ของ submodule จริงๆ แต่เก็บแค่ pointer เท่านั้น เวลา clone repository หลัก เราต้อง initialize และ update submodule ด้วยคำสั่ง git submodule init และ git submodule update

Subtree จะ copy code จาก repository อื่นมาไว้ใน subdirectory ของ repository หลัก ทำให้ repository หลักเก็บ code ของ subtree ทั้งหมด เวลา clone repository หลัก เราไม่ต้องทำอะไรเพิ่มเติม code ของ subtree ก็จะอยู่ใน repository หลักด้วย

โดยทั่วไปแล้ว Submodule จะเหมาะสำหรับกรณีที่เราต้องการอ้างอิง repository อื่นที่แยกจาก repository หลักอย่างชัดเจน ส่วน Subtree จะเหมาะสำหรับกรณีที่เราต้องการรวม code จาก repository อื่นมาไว้ใน repository หลักอย่างถาวร

H3: Squash commits คืออะไร และทำไมถึงต้องใช้?

Squash commits คือการรวม commit หลายๆ commit เข้าด้วยกันเป็น commit เดียว เหมาะสำหรับกรณีที่เรามี commit เล็กๆ น้อยๆ หลาย commit ที่เกี่ยวข้องกัน แล้วเราต้องการรวม commit เหล่านั้นให้เป็น commit ที่มีความหมายมากขึ้น

ผมเคยใช้ squash commits ตอนที่ผมทำ feature ใหม่ แล้วผม commit ไปหลาย commit แต่ละ commit ก็เป็นการเปลี่ยนแปลงเล็กๆ น้อยๆ ที่เกี่ยวข้องกัน พอ feature เสร็จแล้ว ผมก็ squash commit เหล่านั้นให้เป็น commit เดียวที่มี commit message อธิบายว่า feature นั้นคืออะไร

การใช้ squash commits จะช่วยให้ history ของ Git สะอาดและอ่านง่ายขึ้น ทำให้คนอื่น (รวมถึงตัวเราเองในอนาคต) เข้าใจการเปลี่ยนแปลงของโค้ดได้ง่ายขึ้น

วิธี squash commits คือใช้คำสั่ง git rebase -i HEAD~<number-of-commits> แล้วเปลี่ยนคำสั่ง `pick` เป็น `squash` หรือ `s` สำหรับ commit ที่เราต้องการ squash แล้ว Git จะเปิด editor ให้เราแก้ไข commit message ของ commit ใหม่

ตารางสรุปคำสั่ง Git ที่ใช้บ่อย

คำสั่ง คำอธิบาย
git init สร้าง Git repository ใหม่
git clone <url> Clone repository จาก URL
git add <file> เพิ่มไฟล์ไปที่ staging area
git commit -m "<message>" Commit การเปลี่ยนแปลงพร้อม message
git push Push การเปลี่ยนแปลงไปที่ remote repository
git pull Pull การเปลี่ยนแปลงจาก remote repository
git status แสดงสถานะของ working directory
git log แสดง history ของ commit
git branch แสดง list ของ branch
git checkout <branch> สลับไปยัง branch ที่ระบุ
git merge <branch> รวม branch ที่ระบุเข้ากับ branch ปัจจุบัน
git rebase <branch> Rebase branch ปัจจุบันบน branch ที่ระบุ
git diff แสดงความแตกต่างระหว่าง working directory กับ staging area
git reset ยกเลิกการเปลี่ยนแปลงใน staging area
git revert <commit> สร้าง commit ใหม่ที่ยกเลิกการเปลี่ยนแปลงจาก commit ที่ระบุ

📰 บทความล่าสุดจาก SiamCafe

🗺️ ดูบทความทั้งหมด — Sitemap SiamCafe Blog