Lệnh Git: bảng tra cứu với ví dụ dùng hằng ngày
Các lệnh Git cơ bản gồm git init và git clone để tạo kho, git status, git add và git commit để lưu thay đổi, git branch, git switch và git merge để làm việc với nhánh, git push, git fetch và git pull để đồng bộ với máy chủ, cùng git restore, git reset và git revert để hoàn tác.
Dưới đây là bảng tra cứu Git dùng trong thực tế: lệnh được nhóm theo công việc, mỗi lệnh có ví dụ và giải thích ngắn. Nên để bảng này mở cạnh terminal: hầu hết những gì lập trình viên làm với Git trong ngày đều nằm gọn trong 20–30 lệnh ở đây.
Để đọc các lệnh cho có nghĩa, hãy nhớ ba khu vực: thư mục làm việc (tệp trên đĩa), index hay staging area (những gì sẽ vào commit tiếp theo) và kho lưu trữ (lịch sử commit trong thư mục .git). Phần lớn lệnh Git chuyển thay đổi giữa ba khu vực này, hoặc giữa kho cục bộ và kho từ xa.
Cấu hình Git
Các lệnh này chỉ cần chạy một lần sau khi cài đặt. Cờ --global ghi cấu hình vào ~/.gitconfig và áp dụng cho mọi kho của người dùng; không có cờ này thì chỉ áp dụng cho kho hiện tại.
| Lệnh | Tác dụng |
|---|---|
git config --global user.name "Nguyễn Văn An" | Tên tác giả của commit |
git config --global user.email "an@example.com" | Email tác giả của commit |
git config --global init.defaultBranch main | Tên nhánh mặc định cho kho mới |
git config --global core.editor "code --wait" | Trình soạn thảo cho thông điệp commit (ở đây là VS Code) |
git config --global pull.rebase false | Hành vi mặc định của git pull là gộp (merge) |
git config --global core.autocrlf input | Chuyển CRLF thành LF khi commit (macOS/Linux; trên Windows thường dùng true) |
git config --list --show-origin | Hiển thị mọi cấu hình và tệp mà mỗi cấu hình lấy từ đó |
git config --global alias.st status | Bí danh: git st thay cho git status |
git --version | Phiên bản Git đã cài |
git help commit | Hướng dẫn đầy đủ của lệnh (hoặc git commit -h — tóm tắt) |
Tạo và sao chép kho lưu trữ
| Lệnh | Tác dụng |
|---|---|
git init | Tạo kho trống (thư mục .git) trong thư mục hiện tại |
git init my-project | Tạo thư mục my-project và kho bên trong |
git clone https://github.com/user/repo.git | Sao chép kho từ xa kèm toàn bộ lịch sử |
git clone git@github.com:user/repo.git app | Clone qua SSH vào thư mục app |
git clone --depth 1 URL | Clone nông: chỉ commit mới nhất, nhanh và tốn ít dung lượng |
git clone -b develop URL | Clone và chuyển ngay sang nhánh develop |
Chu trình cơ bản: status, add, commit
Đây là trung tâm của công việc hằng ngày: xem đã thay đổi gì, chọn phần cần thiết vào index và ghi lại bằng commit.
| Lệnh | Tác dụng |
|---|---|
git status | Trạng thái: tệp đã sửa, đã chuẩn bị và chưa theo dõi |
git status -s | Dạng ngắn: M — đã sửa, A — đã thêm, ?? — chưa theo dõi |
git add file.txt | Đưa một tệp vào index |
git add . | Đưa mọi thay đổi trong thư mục hiện tại và bên dưới, kể cả việc xóa |
git add -A | Đưa mọi thay đổi trong toàn bộ kho |
git add -p | Chọn tương tác từng đoạn (hunk) thay đổi |
git commit -m "Thêm form đăng nhập" | Tạo commit từ index với thông điệp |
git commit -am "Sửa lỗi chính tả" | Đưa vào index mọi tệp đã theo dõi có thay đổi rồi commit; tệp mới không được đưa vào |
git commit --amend | Viết lại commit cuối: thêm tệp bị quên từ index hoặc sửa thông điệp |
git commit --amend --no-edit | Bổ sung vào commit cuối mà giữ nguyên thông điệp |
git rm file.txt | Xóa tệp khỏi đĩa và khỏi index |
git rm --cached secret.env | Ngừng theo dõi tệp nhưng giữ nó trên đĩa |
git mv old.js new.js | Đổi tên hoặc di chuyển tệp |
Kịch bản điển hình:
git status
git add src/login.js src/login.css
git diff --staged # kiểm tra những gì sẽ vào commit
git commit -m "Thêm form đăng nhập"
Đừng dùng --amend với commit đã được đẩy lên nhánh chung: nó tạo commit mới với hash khác, và đồng nghiệp sẽ phải xử lý sự lệch lịch sử.
Xem lịch sử và thay đổi
| Lệnh | Tác dụng |
|---|---|
git log | Lịch sử commit của nhánh hiện tại |
git log --oneline | Mỗi commit trên một dòng: hash rút gọn và tiêu đề |
git log --oneline --graph --all | Đồ thị mọi nhánh trong terminal |
git log -p file.txt | Lịch sử tệp kèm diff của từng commit |
git log --author="Anna" --since="2 weeks ago" | Lọc theo tác giả và thời gian |
git log -S "getUser" | Các commit có thêm hoặc xóa chuỗi getUser |
git log main..feature | Các commit có trong feature nhưng không có trong main |
git diff | Thay đổi trong thư mục làm việc, chưa đưa vào index |
git diff --staged | Thay đổi trong index so với commit cuối (cũng viết là --cached) |
git diff main feature | Khác biệt giữa đỉnh của hai nhánh |
git diff HEAD~3 -- src/ | Thay đổi trong thư mục src của ba commit gần nhất |
git show a1b2c3d | Thông tin và diff của một commit |
git show HEAD:README.md | Nội dung tệp trong commit cuối |
git blame app.js | Ai và trong commit nào đã sửa từng dòng lần cuối |
git shortlog -sn | Số commit theo từng tác giả |
Tham chiếu tới commit rất hữu ích: HEAD — commit hiện tại, HEAD~1 — cha của nó, HEAD~3 — lùi ba bước theo cha thứ nhất, HEAD^2 — cha thứ hai của commit gộp.
Nhánh: tạo, chuyển, xóa
Từ phiên bản 2.23, Git có git switch cho nhánh và git restore cho tệp — chúng tách ra từ git checkout vốn quá nhiều chức năng. Cách viết cũ vẫn hoạt động.
| Lệnh | Tác dụng |
|---|---|
git branch | Danh sách nhánh cục bộ, nhánh hiện tại có dấu * |
git branch -a | Nhánh cục bộ và nhánh từ xa (remote-tracking) |
git branch -vv | Nhánh kèm commit cuối và số commit vượt/tụt so với upstream |
git branch feature/login | Tạo nhánh mà không chuyển sang |
git switch feature/login | Chuyển sang nhánh |
git switch -c feature/login | Tạo nhánh và chuyển sang (tương đương git checkout -b) |
git switch - | Quay lại nhánh trước đó |
git branch -m new-name | Đổi tên nhánh hiện tại |
git branch -d feature/login | Xóa nhánh nếu đã được gộp |
git branch -D feature/login | Xóa nhánh bắt buộc, kể cả khi chưa gộp |
git branch --merged | Các nhánh đã gộp vào nhánh hiện tại — ứng viên để xóa |
Gộp và rebase
| Lệnh | Tác dụng |
|---|---|
git merge feature | Gộp feature vào nhánh hiện tại (fast-forward nếu có thể) |
git merge --no-ff feature | Luôn tạo commit gộp |
git merge --squash feature | Đưa toàn bộ thay đổi của nhánh vào index thành một lần, rồi git commit |
git merge --abort | Hủy lần gộp có xung đột và quay về trạng thái ban đầu |
git rebase main | Đặt các commit của nhánh hiện tại lên trên main |
git rebase -i HEAD~4 | Tương tác: gộp (squash), đổi tên, sắp xếp, xóa 4 commit cuối |
git rebase --continue | Tiếp tục sau khi đã giải quyết xung đột |
git rebase --abort | Hủy hoàn toàn rebase |
git cherry-pick a1b2c3d | Áp dụng một commit vào nhánh hiện tại thành commit mới |
Cách giải quyết xung đột khi gộp hầu như luôn giống nhau:
git merge feature
# CONFLICT (content): Merge conflict in app.js
git status # các tệp nằm ở mục "both modified"
# sửa app.js, xóa các dấu <<<<<<< ======= >>>>>>>
git add app.js
git commit # Git sẽ gợi ý sẵn thông điệp cho commit gộp
Quy tắc chính khi rebase: không rebase các commit đã nằm trên nhánh chung và đang là nền cho công việc của người khác.
Làm việc với kho từ xa
| Lệnh | Tác dụng |
|---|---|
git remote -v | Danh sách remote và địa chỉ |
git remote add origin git@github.com:user/repo.git | Kết nối kho từ xa với tên origin |
git remote set-url origin ĐỊA_CHỈ_MỚI | Đổi địa chỉ remote (ví dụ từ HTTPS sang SSH) |
git remote remove upstream | Ngắt kết nối remote |
git fetch | Tải commit và nhánh mới, không đụng tới tệp của bạn |
git fetch --prune | Như trên, cộng xóa các tham chiếu tới nhánh đã bị xóa trên máy chủ |
git pull | git fetch + gộp nhánh upstream vào nhánh hiện tại |
git pull --rebase | git fetch + rebase các commit của bạn lên trên phần vừa tải |
git push | Gửi commit của nhánh hiện tại lên upstream |
git push -u origin feature/login | Lần gửi đầu tiên của nhánh, kèm thiết lập upstream |
git push --force-with-lease | Ghi đè nhánh từ xa, chỉ khi không có commit mới của người khác trên đó |
git push origin --delete feature/login | Xóa nhánh trên máy chủ |
git push --tags | Gửi mọi thẻ cục bộ |
Thay vì git push --force, hãy quen dùng --force-with-lease: nếu đồng nghiệp đã kịp push vào cùng nhánh, lệnh sẽ từ chối ghi đè công việc của họ.
Hoàn tác thay đổi
Đây là phần dễ gây hoảng nhất của Git. Câu hỏi quan trọng trước khi chọn lệnh: thay đổi đang ở trong tệp, đã ở index, đã là commit cục bộ hay đã là commit công bố?
| Tình huống | Lệnh |
|---|---|
| Hủy chỉnh sửa trong tệp (đưa về như commit cuối) | git restore app.js |
| Gỡ tệp khỏi index, giữ nguyên chỉnh sửa | git restore --staged app.js |
| Lấy tệp từ một commit cụ thể | git restore --source=a1b2c3d app.js |
| Hủy commit cuối, giữ thay đổi trong index | git reset --soft HEAD~1 |
| Hủy commit cuối, giữ thay đổi trong tệp | git reset HEAD~1 (chế độ --mixed mặc định) |
| Xóa commit cuối và mọi thay đổi của nó | git reset --hard HEAD~1 |
| Hoàn tác commit đã công bố bằng commit đảo ngược | git revert a1b2c3d |
| Hoàn tác commit gộp (merge) | git revert -m 1 <hash-gộp> |
| Xem tệp chưa theo dõi nào sẽ bị xóa | git clean -n |
| Xóa tệp và thư mục chưa theo dõi | git clean -fd |
| Tìm commit «đã mất» sau reset hoặc rebase | git reflog, sau đó git reset --hard HEAD@{2} |
git reset --hard và git clean -f xóa vĩnh viễn các thay đổi chưa commit: reflog chỉ lưu commit, không lưu chỉnh sửa trong thư mục làm việc. Trước khi chạy chúng, hãy git stash hoặc ít nhất là xem git status.
Stash: cất tạm việc đang làm dở
| Lệnh | Tác dụng |
|---|---|
git stash | Cất thay đổi của các tệp đã theo dõi và làm sạch thư mục làm việc |
git stash push -u -m "wip: form" | Cất cả tệp chưa theo dõi, kèm mô tả |
git stash list | Danh sách các bản cất: stash@{0}, stash@{1}… |
git stash show -p stash@{0} | Xem diff của một bản cất |
git stash pop | Lấy lại bản cất gần nhất và xóa khỏi danh sách |
git stash apply stash@{1} | Lấy lại bản cất, giữ nó trong danh sách |
git stash drop stash@{1} | Xóa một bản cất |
git stash branch fix-form | Tạo nhánh từ commit nơi đã cất và áp dụng bản cất |
Thẻ và phát hành
| Lệnh | Tác dụng |
|---|---|
git tag | Danh sách thẻ |
git tag -a v1.2.0 -m "Bản phát hành 1.2.0" | Thẻ chú thích với tác giả, ngày và thông điệp |
git tag v1.2.0 a1b2c3d | Thẻ nhẹ trên một commit cụ thể |
git push origin v1.2.0 | Gửi một thẻ |
git tag -d v1.2.0 | Xóa thẻ cục bộ |
git push origin --delete v1.2.0 | Xóa thẻ trên máy chủ |
git describe --tags | Thẻ gần nhất và số commit sau nó, ví dụ v1.2.0-3-ga1b2c3d |
Lệnh nâng cao
| Lệnh | Tác dụng |
|---|---|
git bisect start, git bisect bad, git bisect good v1.1.0 | Tìm nhị phân commit gây lỗi; kết thúc bằng git bisect reset |
git worktree add ../hotfix main | Thư mục làm việc thứ hai với nhánh khác trong cùng kho |
git submodule update --init --recursive | Tải submodule sau khi clone |
git grep "TODO" | Tìm nhanh trong các tệp đã theo dõi |
git format-patch -1 HEAD / git apply fix.patch | Lưu một commit thành tệp patch và áp dụng patch vào thư mục làm việc |
git gc | Nén đối tượng và dọn kho (thường Git tự làm việc này) |
Lỗi thường gặp và cách sửa
Commit nhầm vào main thay vì nhánh mới
Nếu commit chưa được gửi đi, tạo nhánh tại commit hiện tại rồi đưa main lùi lại:
git branch feature/login # nhánh trỏ tới commit của bạn
git reset --hard HEAD~1 # main lùi lại một bước
git switch feature/login
Quên thêm tệp vào commit cuối
git add forgotten.js
git commit --amend --no-edit
Push bị từ chối: rejected, non-fast-forward
Trên máy chủ có commit mà bạn chưa có. Lấy chúng về trước rồi mới gửi:
git pull --rebase
git push
Lỡ commit tệp chứa mật khẩu
Gỡ nó khỏi theo dõi và thêm vào .gitignore: git rm --cached .env, rồi commit. Nếu commit đã công bố, hãy coi bí mật là đã lộ và cấp lại — nó vẫn còn trong lịch sử.
Tóm lại
Với công việc hằng ngày, một bộ lệnh ngắn là đủ: status, add, commit, switch, merge, pull, push và log --oneline. Lệnh hoàn tác — restore, reset, revert — chọn theo việc commit đã công bố hay chưa, còn reflog là lưới an toàn cuối cùng. Mọi lệnh trong bảng này được thực hành trong khóa học Git, nơi bạn thử từng lệnh trên kho của chính mình.
Câu hỏi thường gặp
Người mới cần biết bao nhiêu lệnh Git?
Để bắt đầu, 10–12 lệnh là đủ: init, clone, status, add, commit, log, diff, branch, switch, merge, pull và push. Các lệnh còn lại học dần khi gặp công việc cần đến.
git switch khác git checkout ở điểm nào?
git switch chỉ chuyển và tạo nhánh, còn git checkout còn khôi phục tệp. Việc tách thành switch và restore nhằm tránh nhầm lẫn nhánh với tệp và vô tình làm mất chỉnh sửa.
Làm sao xem hướng dẫn của một lệnh Git?
Chạy git help tên-lệnh để xem hướng dẫn đầy đủ, hoặc git tên-lệnh -h để xem danh sách cờ ngắn gọn. Tài liệu tương tự cũng có trên git-scm.com.
Có thể rút ngắn các lệnh Git dài không?
Có, bằng bí danh: git config --global alias.lg "log --oneline --graph --all" để gõ git lg.
Các lệnh này có chạy trên Windows không?
Có, lệnh giống nhau trên mọi hệ điều hành. Trên Windows chúng chạy tốt trong Git Bash, PowerShell hoặc terminal của trình soạn thảo mã.
Chủ đề này được giảng chi tiết kèm thực hành trong khóa học “Git с нуля до уверенного разработчика”.
- Первый репозиторий: init, add, commit и магия индекса
- Читаем историю: log, diff, show и навигация по прошлому
- Ветки: параллельная реальность вашего кода
- Отменяем ошибки: restore, reset, revert — правильно и опасно
- GitHub и удалённые репозитории: ваш код в облаке
- Продвинутые инструменты: rebase, stash, cherry-pick и теги