ชีตสรุป

คำสั่ง Git: ชีตสรุปพร้อมตัวอย่างสำหรับใช้ทุกวัน

อัปเดต: · Skillaria.Top

คำสั่ง Git หลักประกอบด้วย git init และ git clone สำหรับสร้างรีโพซิทอรี git status, git add และ git commit สำหรับบันทึกการเปลี่ยนแปลง git branch, git switch และ git merge สำหรับการทำงานกับบรานช์ git push, git fetch และ git pull สำหรับซิงก์กับเซิร์ฟเวอร์ และ git restore, git reset และ git revert สำหรับย้อนการเปลี่ยนแปลง

ด้านล่างคือชีตสรุป Git ที่ใช้งานได้จริง คำสั่งจัดกลุ่มตามงาน และแต่ละคำสั่งมีตัวอย่างพร้อมคำอธิบายสั้น ๆ ควรเปิดค้างไว้ข้างเทอร์มินัล เพราะงานเกือบทั้งหมดที่นักพัฒนาทำกับ Git ในหนึ่งวันสรุปได้เป็น 20–30 คำสั่งในตารางเหล่านี้

เพื่อให้คำสั่งเข้าใจได้ ให้จดจำพื้นที่สามส่วน ได้แก่ โฟลเดอร์งาน (ไฟล์บนดิสก์) อินเด็กซ์ หรือ staging area (สิ่งที่จะเข้าสู่คอมมิตถัดไป) และ รีโพซิทอรี (ประวัติคอมมิตในโฟลเดอร์ .git) คำสั่ง Git ส่วนใหญ่ย้ายการเปลี่ยนแปลงระหว่างพื้นที่ทั้งสามนี้ หรือระหว่างรีโมตกับเครื่องคุณ

ตั้งค่า Git

คำสั่งเหล่านี้รันครั้งเดียวหลังติดตั้ง แฟล็ก --global เขียนการตั้งค่าไปยัง ~/.gitconfig และมีผลกับทุกรีโพของผู้ใช้ หากไม่ใส่ แฟล็กจะมีผลเฉพาะรีโพปัจจุบัน

คำสั่งสิ่งที่ทำ
git config --global user.name "ชื่อ นามสกุล"ชื่อผู้เขียนคอมมิต
git config --global user.email "you@example.com"อีเมลผู้เขียนคอมมิต
git config --global init.defaultBranch mainชื่อบรานช์เริ่มต้นของรีโพใหม่
git config --global core.editor "code --wait"บรรณาธิการสำหรับข้อความคอมมิต (ที่นี่คือ VS Code)
git config --global pull.rebase falseพฤติกรรมเริ่มต้นของ git pull คือ merge
git config --global core.autocrlf inputแปลง CRLF เป็น LF ตอนคอมมิต (macOS/Linux บน Windows มักใช้ true)
git config --list --show-originแสดงการตั้งค่าทั้งหมดและไฟล์ที่มาของแต่ละค่า
git config --global alias.st statusตั้งชื่อย่อ: git st แทน git status
git --versionเวอร์ชัน Git ที่ติดตั้งอยู่
git help commitคู่มือฉบับเต็มของคำสั่ง (หรือ git commit -h แบบย่อ)

สร้างและโคลนรีโพซิทอรี

คำสั่งสิ่งที่ทำ
git initสร้างรีโพว่าง(โฟลเดอร์ .git) ในไดเรกทอรีปัจจุบัน
git init my-projectสร้างโฟลเดอร์ my-project และรีโพในนั้น
git clone https://github.com/user/repo.gitคัดลอกรีโมตพร้อมประวัติทั้งหมด
git clone git@github.com:user/repo.git appโคลนผ่าน SSH ลงโฟลเดอร์ app
git clone --depth 1 URLโคลนแบบตื้น: เฉพาะคอมมิตล่าสุด รวดเร็วและใช้พื้นที่น้อย
git clone -b develop URLโคลนแล้วสลับไปยังบรานช์ develop ทันที

วงจรพื้นฐาน: status, add, commit

นี่คือหัวใจของงานประจำวัน ดูว่าอะไรเปลี่ยนไป เลือกสิ่งที่ต้องการลงอินเด็กซ์ แล้วบันทึกเป็นคอมมิต

คำสั่งสิ่งที่ทำ
git statusสถานะ: ไฟล์ที่แก้ไข ไฟล์ที่อยู่ในอินเด็กซ์ และไฟล์ที่ไม่ถูกติดตาม
git status -sรูปแบบย่อ: M แก้ไขแล้ว, A เพิ่มแล้ว, ?? ไม่ถูกติดตาม
git add file.txtเพิ่มไฟล์เข้าอินเด็กซ์
git add .เพิ่มการเปลี่ยนแปลงทั้งหมดในไดเรกทอรีปัจจุบันและที่อยู่ข้างใน รวมถึงการลบ
git add -Aเพิ่มการเปลี่ยนแปลงทั้งหมดในรีโพ
git add -pเลือกส่วน (hunk) ของการเปลี่ยนแปลงทีละส่วนแบบโต้ตอบ
git commit -m "เพิ่มฟอร์มเข้าสู่ระบบ"สร้างคอมมิตจากอินเด็กซ์พร้อมข้อความ
git commit -am "แก้คำผิด"ใส่ไฟล์ที่ถูกติดตามและแก้ไขแล้วทั้งหมดเข้าอินเด็กซ์แล้วคอมมิต ไฟล์ใหม่จะไม่รวมอยู่ด้วย
git commit --amendเขียนคอมมิตล่าสุดใหม่: เพิ่มสิ่งที่ลืมจากอินเด็กซ์ หรือแก้ข้อความ
git commit --amend --no-editเพิ่มเข้าคอมมิตล่าสุดโดยไม่เปลี่ยนข้อความ
git rm file.txtลบไฟล์จากดิสก์และจากอินเด็กซ์
git rm --cached secret.envหยุดติดตามไฟล์ แต่คงไว้บนดิสก์
git mv old.js new.jsเปลี่ยนชื่อหรือย้ายไฟล์

สถานการณ์ทั่วไปเป็นดังนี้

git status
git add src/login.js src/login.css
git diff --staged          # ตรวจว่าอะไรจะเข้าสู่คอมมิต
git commit -m "เพิ่มฟอร์มเข้าสู่ระบบ"

อย่าใช้ --amend กับคอมมิตที่ถูกส่งไปยังบรานช์ร่วมแล้ว เพราะจะสร้างคอมมิตใหม่ที่มีแฮชต่างออกไป และเพื่อนร่วมทีมจะต้องจัดการประวัติที่ไม่ตรงกัน

ดูประวัติและการเปลี่ยนแปลง

คำสั่งสิ่งที่ทำ
git logประวัติคอมมิตของบรานช์ปัจจุบัน
git log --onelineแต่ละคอมมิตในหนึ่งบรรทัด: แฮชสั้นและหัวข้อ
git log --oneline --graph --allกราฟของทุกบรานช์ในเทอร์มินัล
git log -p file.txtประวัติของไฟล์พร้อมดิฟของแต่ละคอมมิต
git log --author="สมชาย" --since="2 weeks ago"กรองตามผู้เขียนและวันที่
git log -S "getUser"คอมมิตที่มีการเพิ่มหรือลบข้อความ getUser
git log main..featureคอมมิตที่อยู่ใน feature แต่ไม่อยู่ใน main
git diffการเปลี่ยนแปลงในโฟลเดอร์งานที่ยังไม่เข้าอินเด็กซ์
git diff --stagedการเปลี่ยนแปลงในอินเด็กซ์เทียบกับคอมมิตล่าสุด (เหมือน --cached)
git diff main featureความต่างระหว่างปลายของสองบรานช์
git diff HEAD~3 -- src/การเปลี่ยนแปลงในโฟลเดอร์ src ของสามคอมมิตล่าสุด
git show a1b2c3dข้อมูลและดิฟของคอมมิตหนึ่ง
git show HEAD:README.mdเนื้อหาของไฟล์ในคอมมิตล่าสุด
git blame app.jsใครแก้แต่ละบรรทัดล่าสุดในคอมมิตใด
git shortlog -snจำนวนคอมมิตต่อผู้เขียน

การอ้างอิงคอมมิตใช้บ่อยมาก: HEAD คือคอมมิตปัจจุบัน HEAD~1 คือพาเรนต์ของมัน HEAD~3 คือย้อนสามขั้นตามพาเรนต์แรก และ HEAD^2 คือพาเรนต์ที่สองของ merge commit

บรานช์: สร้าง สลับ ลบ

ตั้งแต่เวอร์ชัน 2.23 Git มี git switch สำหรับบรานช์ และ git restore สำหรับไฟล์ ซึ่งแยกหน้าที่ของ git checkout ที่ทำงานหลายอย่างเกินไป รูปแบบเก่ายังใช้งานได้

คำสั่งสิ่งที่ทำ
git branchรายการบรานช์ในเครื่อง บรานช์ปัจจุบันมีเครื่องหมาย *
git branch -aบรานช์ในเครื่องและบรานช์รีโมต (remote-tracking)
git branch -vvบรานช์พร้อมคอมมิตล่าสุดและจำนวนที่ตามหลังหรือนำหน้า upstream
git branch feature/loginสร้างบรานช์โดยไม่สลับ
git switch feature/loginสลับไปยังบรานช์
git switch -c feature/loginสร้างบรานช์และสลับไปทันที (เทียบเท่า git checkout -b)
git switch -กลับไปยังบรานช์ก่อนหน้า
git branch -m new-nameเปลี่ยนชื่อบรานช์ปัจจุบัน
git branch -d feature/loginลบบรานช์ เมื่อถูก merge แล้วเท่านั้น
git branch -D feature/loginบังคับลบบรานช์ แม้ยังไม่ถูก merge
git branch --mergedบรานช์ที่ถูก merge เข้าบรานช์ปัจจุบันแล้ว เป็นตัวเลือกสำหรับการลบ

Merge และ rebase

คำสั่งสิ่งที่ทำ
git merge featureรวม feature เข้าบรานช์ปัจจุบัน (fast-forward หากทำได้)
git merge --no-ff featureสร้าง merge commit เสมอ
git merge --squash featureรวมการเปลี่ยนแปลงทั้งหมดของบรานช์เข้าอินเด็กซ์เป็นชุดเดียว แล้วจึง git commit
git merge --abortยกเลิกการ merge ที่มี conflict และกลับไปยังสถานะเดิม
git rebase mainย้ายคอมมิตของบรานช์ปัจจุบันไปวางทับ main
git rebase -i HEAD~4แบบโต้ตอบ: รวม (squash) เปลี่ยนชื่อ จัดลำดับ หรือลบสี่คอมมิตล่าสุด
git rebase --continueทำต่อหลังแก้ conflict แล้ว
git rebase --abortยกเลิก rebase ทั้งหมด
git cherry-pick a1b2c3dนำหนึ่งคอมมิตมาใช้กับบรานช์ปัจจุบันเป็นคอมมิตใหม่

การแก้ conflict ตอน merge มักเป็นแบบนี้เสมอ:

git merge feature
# CONFLICT (content): Merge conflict in app.js
git status                 # ไฟล์อยู่ในหมวด "both modified"
# แก้ app.js ลบเครื่องหมาย <<<<<<< ======= >>>>>>>
git add app.js
git commit                 # Git เสนอข้อความสำเร็จรูปของ merge commit

กฎสำคัญของ rebase: อย่า rebase คอมมิตที่อยู่ในบรานช์ร่วมแล้ว และเพื่อนร่วมทีมกำลังสร้างงานบนคอมมิตเหล่านั้น

ทำงานกับรีโมตรีโพซิทอรี

คำสั่งสิ่งที่ทำ
git remote -vรายการรีโมตและที่อยู่
git remote add origin git@github.com:user/repo.gitเชื่อมรีโมตชื่อ origin
git remote set-url origin NEW_URLเปลี่ยนที่อยู่ของรีโมต (เช่น จาก HTTPS เป็น SSH)
git remote remove upstreamยกเลิกการเชื่อมรีโมต
git fetchดาวน์โหลดคอมมิตและบรานช์ใหม่ โดยไม่แตะไฟล์ของคุณ
git fetch --pruneเหมือนข้างบน และลบการอ้างอิงถึงบรานช์ที่ถูกลบบนเซิร์ฟเวอร์
git pullgit fetch แล้ว merge บรานช์ upstream เข้าบรานช์ปัจจุบัน
git pull --rebasegit fetch แล้ว rebase คอมมิตของคุณทับสิ่งที่ได้มา
git pushส่งคอมมิตของบรานช์ปัจจุบันไปยัง upstream
git push -u origin feature/loginส่งบรานช์ครั้งแรกพร้อมตั้ง upstream
git push --force-with-leaseเขียนทับบรานช์รีโมต เฉพาะเมื่อไม่มีคอมมิตใหม่จากคนอื่นอยู่บนนั้น
git push origin --delete feature/loginลบบรานช์บนเซิร์ฟเวอร์
git push --tagsส่งแท็กในเครื่องทั้งหมด

ให้เปลี่ยนจาก git push --force มาใช้ --force-with-lease แทน หากเพื่อนร่วมทีมได้ push เข้าบรานช์เดียวกันไปแล้ว คำสั่งจะปฏิเสธการเขียนทับงานของเขา

ย้อนการเปลี่ยนแปลง

ส่วนที่ทำให้ประหม่าที่สุดของ Git คำถามสำคัญก่อนเลือกคำสั่งคือ การเปลี่ยนแปลงอยู่ในไฟล์ อยู่ในอินเด็กซ์ อยู่ในคอมมิตในเครื่อง หรืออยู่ในคอมมิตที่เผยแพร่แล้ว

สถานการณ์คำสั่ง
ย้อนการแก้ไขในไฟล์ (กลับไปเหมือนคอมมิตล่าสุด)git restore app.js
นำไฟล์ออกจากอินเด็กซ์ แต่คงการแก้ไขไว้git restore --staged app.js
กู้ไฟล์จากคอมมิตที่ระบุgit restore --source=a1b2c3d app.js
ยกเลิกคอมมิตล่าสุด แต่คงการเปลี่ยนแปลงในอินเด็กซ์git reset --soft HEAD~1
ยกเลิกคอมมิตล่าสุด แต่คงการเปลี่ยนแปลงในไฟล์git reset HEAD~1 (โหมด --mixed เป็นค่าเริ่มต้น)
ลบคอมมิตล่าสุดและการเปลี่ยนแปลงทั้งหมดgit reset --hard HEAD~1
ย้อนคอมมิตที่เผยแพร่แล้วด้วยคอมมิตย้อนกลับใหม่git revert a1b2c3d
ย้อน merge commitgit revert -m 1 <merge-hash>
ดูว่าไฟล์ที่ไม่ถูกติดตามใดจะถูกลบgit clean -n
ลบไฟล์และโฟลเดอร์ที่ไม่ถูกติดตามgit clean -fd
หาคอมมิตที่ "หาย" หลัง reset หรือ rebasegit reflog แล้ว git reset --hard HEAD@{2}

git reset --hard และ git clean -f ลบการเปลี่ยนแปลงที่ยังไม่คอมมิตอย่างถาวร เพราะ reflog เก็บเฉพาะคอมมิต ไม่เก็บการแก้ไขในโฟลเดอร์งาน ก่อนใช้ทั้งสองคำสั่งให้ทำ git stash หรืออย่างน้อยรัน git status

Stash: พักงานที่ยังไม่เสร็จ

คำสั่งสิ่งที่ทำ
git stashเก็บการเปลี่ยนแปลงของไฟล์ที่ถูกติดตามและล้างโฟลเดอร์งาน
git stash push -u -m "wip: ฟอร์ม"เก็บพร้อมไฟล์ที่ไม่ถูกติดตาม และมีป้ายกำกับ
git stash listรายการชุดที่เก็บไว้: stash@{0}, stash@{1}…
git stash show -p stash@{0}ดูดิฟของชุดที่เก็บไว้
git stash popคืนชุดล่าสุดและลบออกจากรายการ
git stash apply stash@{1}คืนชุดโดยคงไว้ในรายการ
git stash drop stash@{1}ลบชุดหนึ่งชุด
git stash branch fix-formสร้างบรานช์จากคอมมิตที่ทำ stash ไว้ แล้วนำชุดนั้นมาใช้

แท็กและรีลีส

คำสั่งสิ่งที่ทำ
git tagรายการแท็ก
git tag -a v1.2.0 -m "รีลีส 1.2.0"แท็กแบบ annotated พร้อมผู้เขียน วันที่ และข้อความ
git tag v1.2.0 a1b2c3dแท็กแบบเบาบนคอมมิตที่ระบุ
git push origin v1.2.0ส่งแท็กหนึ่งอัน
git tag -d v1.2.0ลบแท็กในเครื่อง
git push origin --delete v1.2.0ลบแท็กบนเซิร์ฟเวอร์
git describe --tagsแท็กที่ใกล้ที่สุดและจำนวนคอมมิตหลังแท็ก เช่น v1.2.0-3-ga1b2c3d

คำสั่งขั้นสูง

คำสั่งสิ่งที่ทำ
git bisect start, git bisect bad, git bisect good v1.1.0ค้นหาแบบไบนารีว่าคอมมิตใดทำให้เกิดข้อผิดพลาด จบด้วย git bisect reset
git worktree add ../hotfix mainโฟลเดอร์งานที่สองที่มีบรานช์อื่นจากรีโพเดียวกัน
git submodule update --init --recursiveดาวน์โหลดซับโมดูลหลังการโคลน
git grep "TODO"ค้นหาอย่างรวดเร็วในไฟล์ที่ถูกติดตาม
git format-patch -1 HEAD / git apply fix.patchบันทึกคอมมิตเป็นไฟล์แพตช์ และนำแพตช์ไปใช้กับโฟลเดอร์งาน
git gcบีบอัดอ็อบเจกต์และทำความสะอาดรีโพ (ปกติ Git ทำเองอยู่แล้ว)

ข้อผิดพลาดที่พบบ่อยและวิธีแก้

คอมมิตลงใน main ทั้งที่ควรเป็นบรานช์ใหม่

หากคอมมิตยังไม่ถูกส่ง ให้สร้างบรานช์บนคอมมิตปัจจุบัน แล้วย้อน main กลับไป:

git branch feature/login      # บรานช์ชี้ไปยังคอมมิตของคุณ
git reset --hard HEAD~1       # main ย้อนกลับหนึ่งขั้น
git switch feature/login

ลืมเพิ่มไฟล์เข้าคอมมิตล่าสุด

git add forgotten.js
git commit --amend --no-edit

Push ถูกปฏิเสธ: rejected, non-fast-forward

มีคอมมิตบนเซิร์ฟเวอร์ที่คุณยังไม่มี ให้ดึงมาก่อนแล้วจึงส่ง:

git pull --rebase
git push

คอมมิตไฟล์ที่มีรหัสผ่านโดยไม่ตั้งใจ

นำออกจากการติดตามและเพิ่มลงใน .gitignore: git rm --cached .env แล้วคอมมิต หากคอมมิตถูกส่งไปแล้ว ให้ถือว่าความลับนั้นรั่วไหลและสร้างใหม่ทันที เพราะความลับยังคงอยู่ในประวัติ

สรุป

สำหรับงานประจำวัน ชุดคำสั่งสั้น ๆ ก็เพียงพอ ได้แก่ status, add, commit, switch, merge, pull, push และ log --oneline คำสั่งย้อนการเปลี่ยนแปลง ได้แก่ restore, reset และ revert ให้เลือกตามว่าคอมมิตถูกเผยแพร่หรือยัง ส่วน reflog ให้จำไว้เป็นตาข่ายนิรภัยสำหรับกรณีฉุกเฉิน คำสั่ง Git ทั้งหมดในชีตนี้เราอธิบายอย่างลงมือทำในหลักสูตร Git โดยทดลองทุกคำสั่งในรีโพของคุณเอง

คำถามที่พบบ่อย

มือใหม่ควรรู้คำสั่ง Git กี่คำสั่ง?

เพื่อเริ่มต้นเพียงพอแล้วที่ 10–12 คำสั่ง ได้แก่ init, clone, status, add, commit, log, diff, branch, switch, merge, pull และ push คำสั่งที่เหลือจะเรียนรู้เมื่อมีงานที่ต้องใช้

git switch ต่างจาก git checkout อย่างไร?

git switch สลับและสร้างบรานช์เท่านั้น ส่วน git checkout ยังกู้ไฟล์ได้ด้วย การแยก switch กับ restore ทำให้ไม่เผลอทับการแก้ไขเพราะสับสนระหว่างบรานช์กับไฟล์

ดูคู่มือของคำสั่ง Git ได้อย่างไร?

รัน git help ชื่อคำสั่ง เพื่อดูคู่มือฉบับเต็ม หรือ git ชื่อคำสั่ง -h เพื่อดูรายการแฟล็กแบบย่อ เอกสารเดียวกันมีบน git-scm.com

ทำให้คำสั่ง Git ยาว ๆ สั้นลงได้หรือไม่?

ได้ ด้วยชื่อย่อ (alias) เช่น git config --global alias.lg "log --oneline --graph --all" แล้วพิมพ์ git lg

คำสั่งเหล่านี้ใช้ได้บน Windows หรือไม่?

ได้ คำสั่งเหมือนกันทุกระบบ บน Windows สะดวกที่จะรันใน Git Bash, PowerShell หรือเทอร์มินัลของโปรแกรมแก้ไขโค้ด