Mẹo & Thủ thuật
9 phút đọc2 tháng 6, 20263

git-tips/tips: Kho cheat sheet Git mà dev nào cũng nên bookmark

Tổng hợp và phân tích chi tiết những git tips thực chiến nhất từ repo 21k+ stars, kèm ví dụ copy-paste được ngay vào terminal.

N

Nguyễn Nhật Long

@nguyennhatlong1303

Mình cá là hầu hết anh em dev đều dùng Git hàng ngày, nhưng thực tế thì đa số chúng ta chỉ xoay quanh mấy lệnh quen thuộc: git add, git commit, git push, git pull, rồi thỉnh thoảng git merge hay git checkout. Gặp tình huống phức tạp hơn một chút kiểu như cần sửa commit message cũ, cherry-pick một commit từ branch khác, hay recover lại file đã xóa là bắt đầu Google tá lả. Mình cũng từng như vậy suốt mấy năm đầu đi làm.

Rồi mình tình cờ gặp repo git-tips/tips trên GitHub. Repo này hiện đã có hơn 21.7k stars, và nó đơn giản là một bộ sưu tập cực kỳ gọn gàng những git commands hay dùng nhất, được phân loại rõ ràng, kèm giải thích ngắn gọn. Nghe thì đơn giản, nhưng cái hay là nó tập trung vào những tình huống thực tế mà dev gặp hàng ngày, không phải mấy thứ lý thuyết xa vời.

Hôm nay mình sẽ đi sâu vào những tips mà mình thấy thực sự hữu ích, kèm context giải thích khi nào nên dùng và tại sao. Không chỉ copy-paste command, mà mình muốn anh em hiểu được flow đằng sau.

Những tình huống "cứu mạng" mà ai cũng gặp

Sửa commit vừa push nhầm

Đây là tình huống kinh điển. Bạn vừa commit xong, nhìn lại thấy typo trong message, hoặc quên add một file. Thay vì tạo thêm một commit mới kiểu "fix typo" hay "forgot to add file" (nhìn history xấu kinh khủng), bạn dùng:

Terminal
1# Sửa commit message gần nhất
2git commit --amend -m "Message mới đúng chính tả"
3
4# Thêm file quên vào commit gần nhất mà KHÔNG đổi message
5git add forgotten-file.js
6git commit --amend --no-edit

Lưu ý quan trọng: nếu bạn đã push commit đó lên remote rồi, thì sau khi amend bạn phải git push --force-with-lease. Mình nhấn mạnh là --force-with-lease chứ không phải --force, vì --force-with-lease sẽ check xem có ai khác đã push lên branch đó chưa nếu có thì nó sẽ từ chối, tránh việc bạn overwrite code của đồng nghiệp.

Terminal
1git push --force-with-lease

Theo kinh nghiệm của mình, cái --force-with-lease này nên được set làm default thay cho --force luôn. Bạn có thể alias nó:

Terminal
1git config --global alias.pushf 'push --force-with-lease'

Recover file đã xóa

Bạn lỡ xóa một file và đã commit mất rồi? Đừng hoảng. Git lưu lại mọi thứ:

Terminal
1# Tìm commit cuối cùng mà file đó còn tồn tại
2git rev-list -n 1 HEAD -- path/to/deleted-file.js
3
4# Restore file từ commit đó
5git checkout <commit-hash>^ -- path/to/deleted-file.js

Dấu ^ sau commit hash nghĩa là "commit ngay trước đó" tức là commit mà file vẫn còn tồn tại, chứ không phải commit đã xóa nó.

Quay lại branch trước đó

Cái này nhỏ nhưng tiết kiệm thời gian cực kỳ:

Terminal
1git checkout -

Giống như cd - trong terminal vậy nó switch về branch bạn vừa rời đi. Khi bạn đang nhảy qua nhảy lại giữa mainfeature-branch thì cái này nhanh hơn gõ tên branch nhiều.

Làm việc với branches như một pro

Repo git-tips có cả một section về branching mà mình thấy rất đáng để nắm vững.

Xem tất cả branches đã merge vào master

Terminal
1git branch --merged master

Cái này cực hữu ích khi bạn muốn cleanup branches cũ. Sau khi list ra, bạn có thể xóa hàng loạt:

Terminal
1# Xóa tất cả local branches đã merge vào master (trừ master)
2git branch --merged master | grep -v '^\* master$' | xargs -n 1 git branch -d

Mình hay chạy cái này mỗi tuần vì sau một thời gian, local repo toàn branches cũ không còn dùng nữa, nhìn git branch ra cả trang.

Xem branches được sắp xếp theo commit gần nhất

Terminal
1git for-each-ref --sort=-committerdate --format='%(refname:short) %(committerdate:relative)' refs/heads/

Output sẽ kiểu:

TEXT
1feature/payment 2 hours ago
2fix/login-bug 3 days ago
3main 5 days ago
4old-experiment 3 months ago

Nhìn là biết ngay branch nào đang active, branch nào nên xóa đi. Mình alias cái này thành git recent:

Terminal
1git config --global alias.recent 'for-each-ref --sort=-committerdate --format="%(refname:short) %(committerdate:relative)" refs/heads/'

Cherry-pick và những pha cứu nguy ngoạn mục

Cherry-pick là khi bạn muốn lấy đúng một commit cụ thể từ branch khác sang branch hiện tại, thay vì merge cả branch. Tình huống thực tế: đồng nghiệp fix một bug trên branch feature-x, mà bạn cũng cần cái fix đó trên branch feature-y của mình, nhưng chưa muốn merge cả feature-x vào.

Terminal
1# Lấy commit abc123 từ branch khác
2git cherry-pick abc123
3
4# Cherry-pick nhiều commits
5git cherry-pick abc123 def456
6
7# Cherry-pick nhưng không tự động commit (để bạn review trước)
8git cherry-pick abc123 --no-commit

Anh em lưu ý: cherry-pick tạo ra một commit mới với hash khác, nên nếu sau này merge branch lại thì có thể gặp duplicate changes. Không phải lúc nào cherry-pick cũng là giải pháp tốt nhất đôi khi rebase sạch hơn.

Stash nâng cao không chỉ là git stash rồi git stash pop

Đa số anh em chỉ dùng stash ở mức cơ bản. Nhưng git-tips chỉ ra mấy trick hay:

Terminal
1# Stash kèm message để nhớ đang stash cái gì
2git stash save "WIP: đang làm dở payment flow"
3
4# Xem list tất cả stash
5git stash list
6
7# Apply một stash cụ thể (không phải cái mới nhất)
8git stash apply stash@{2}
9
10# Lấy MỘT FILE cụ thể từ stash
11git checkout stash@{0} -- path/to/file.js

Cái cuối cùng là gem thực sự. Nhiều khi bạn stash cả đống thay đổi nhưng chỉ cần lấy lại một file thay vì pop cả stash ra rồi lại phải xử lý conflict, bạn checkout đúng file đó thôi.

Những commands mà mình ước biết sớm hơn

Đây là bảng so sánh một số tình huống phổ biến và cách xử lý "thông thường" vs cách tối ưu hơn từ git-tips:

Cái git bisect đặc biệt đáng nói. Nó dùng binary search để tìm commit gây bug. Bạn chỉ cần nói cho Git biết commit nào "good" (chưa có bug) và commit nào "bad" (đã có bug), rồi Git sẽ tự checkout các commit ở giữa để bạn test. Thay vì phải check 100 commits, bạn chỉ cần check khoảng 7 commits (log₂ 100). Mình đã dùng cái này để tìm một regression bug trong project có hàng nghìn commits tiết kiệm cả buổi chiều.

Tình huốngCách hay làmCách tối ưu hơn
Xem diff ngắn gọn`git diff` (output dài)`git diff --stat` (chỉ hiện tên file + số dòng thay đổi)
Xem log đẹp`git log``git log --oneline --graph --decorate --all`
Tìm commit gây bugCheckout từng commit thủ công`git bisect start` → `git bisect bad` → `git bisect good <hash>`
Xóa branch remoteLên GitHub xóa tay`git push origin --delete branch-name`
Xem ai sửa dòng nàoMở GitHub blame`git blame path/to/file.js`
Commit rỗng (trigger CI)Sửa linh tinh rồi commit`git commit --allow-empty -m "trigger CI"`
Xem status nhanh`git status` (verbose)`git status -sb` (short + branch info)
Terminal
1git bisect start
2git bisect bad # commit hiện tại có bug
3git bisect good v1.0.0 # tag/commit mà bạn biết chắc chưa có bug
4# Git sẽ checkout commit ở giữa, bạn test rồi đánh dấu:
5git bisect good # nếu commit này OK
6git bisect bad # nếu commit này có bug
7# Lặp lại cho đến khi Git tìm ra commit gây bug
8git bisect reset # quay về branch ban đầu

Stage từng phần của file interactive staging

Đây là feature mà mình thấy ít người biết nhưng cực kỳ powerful:

Terminal
1git add -p

Lệnh này cho phép bạn chọn từng hunk (từng đoạn thay đổi) trong một file để stage, thay vì stage cả file. Tại sao lại cần? Vì đôi khi bạn sửa một file nhưng có 2 thay đổi logic khác nhau ví dụ vừa fix bug vừa refactor tên biến. Bạn muốn tách thành 2 commits riêng biệt cho clean history.

Khi chạy git add -p, Git sẽ hiện từng đoạn thay đổi và hỏi bạn:

  • y stage đoạn này
  • n bỏ qua
  • s split thành đoạn nhỏ hơn
  • e edit thủ công

Mình dùng cái này gần như mỗi ngày. Nó giúp commit history sạch đẹp hơn rất nhiều so với kiểu "commit cả đống thay đổi vào một commit".

CLI tool đi kèm: git-tip

Repo này còn có một CLI tool tên là git-tip cài qua npm:

Terminal
1npm install -g git-tip

Sau đó mỗi lần mở terminal, bạn gõ git-tip là nó random hiện một tip cho bạn. Mình hay bỏ cái này vào .bashrc hoặc .zshrc để mỗi lần mở terminal lên là học được một tip mới:

Terminal
1# Thêm vào cuối ~/.zshrc
2echo "💡 Git tip of the day:"
3git-tip

Cách học kiểu này hiệu quả hơn ngồi đọc cả list một lúc rất nhiều, vì mỗi ngày bạn chỉ tiếp thu một thứ nhỏ, dần dần nó ngấm vào workflow tự nhiên.

Mấy alias mà mình recommend setup ngay

Dựa trên những tips từ repo, đây là bộ alias mình đang dùng hàng ngày:

Terminal
1git config --global alias.co 'checkout'
2git config --global alias.br 'branch'
3git config --global alias.ci 'commit'
4git config --global alias.st 'status -sb'
5git config --global alias.lg 'log --oneline --graph --decorate --all'
6git config --global alias.unstage 'reset HEAD --'
7git config --global alias.last 'log -1 HEAD --stat'
8git config --global alias.pushf 'push --force-with-lease'
9git config --global alias.recent 'for-each-ref --sort=-committerdate --format="%(refname:short) %(committerdate:relative)" refs/heads/'
10git config --global alias.aliases 'config --get-regexp alias'

Cái cuối cùng git aliases để xem lại tất cả alias bạn đã setup vì setup nhiều quá đôi khi quên mất mình có alias gì.

Repo này phù hợp với ai?

Thẳng thắn mà nói, nếu bạn chỉ dùng Git qua GUI (GitKraken, SourceTree, hay VS Code built-in), thì nhiều tips trong này bạn có thể không cần. Nhưng theo kinh nghiệm của mình, hiểu được CLI commands đằng sau giúp bạn debug nhanh hơn khi GUI tool gặp vấn đề, và quan trọng hơn là hiểu được Git thực sự hoạt động như thế nào.

Repo có hơn 21k stars không phải tự nhiên. Nó được maintain tốt, có đóng góp từ cộng đồng, và đặc biệt là có bản dịch tiếng Việt (cùng nhiều ngôn ngữ khác). Mình suggest anh em bookmark lại, không cần đọc hết một lúc cứ mỗi khi gặp tình huống lạ với Git thì vào tìm, khả năng cao là có sẵn solution trong đó rồi.

Còn nếu bạn muốn đọc dạng sách thì repo cũng có bản GitBook interactive đọc trên web khá tiện, có mục lục và tìm kiếm được.

NN

Nguyễn Nhật Long

@nguyennhatlong1303

Nguyễn Nhật Long is a Senior Frontend Engineer and Frontend Team Leader with 7 years of experience building real-time fintech platforms. Specializing in React, Next.js, TypeScript, and React Native, shipping 10+ products across Web, Mobile, Telegram Mini-Apps, and Web3.

Thấy hay? Chia sẻ cho bạn bè!