Git reset revert restore: chọn lệnh đúng

Nội dung

Bài viết so sánh git reset, git revert và git restore theo mục đích sử dụng: sửa staging area, khôi phục file, undo commit chưa push hoặc đảo ngược commit đã push.

Bạn muốn undo thay đổi trong Git nhưng không biết nên dùng reset, revert hay restore? Đây là nhóm lệnh rất dễ nhầm vì đều có vẻ “quay lại”, nhưng tác động của chúng lên commit history, staging area và file local lại khác nhau.

Git reset, revert, restore khác nhau ở mục tiêu: reset di chuyển branch/HEAD hoặc bỏ staging, revert tạo commit mới để đảo ngược commit cũ, còn restore khôi phục file trong working tree hoặc staging area. Bài này sẽ giúp bạn chọn đúng lệnh theo từng tình huống, đặc biệt khi làm việc trong team.

Git reset revert restore khác nhau trong workflow undo code
Reset, revert và restore đều dùng để undo nhưng tác động vào các lớp khác nhau của Git.

Tóm tắt nhanh

  • Git reset revert restore là ba nhóm lệnh undo khác nhau, không nên dùng thay thế máy móc.
  • Git reset phù hợp để undo commit chưa push hoặc bỏ file khỏi staging area.
  • Git revert phù hợp để đảo ngược commit đã push vì không xóa lịch sử chung.
  • Git restore phù hợp để khôi phục file hoặc bỏ thay đổi local theo cách rõ nghĩa hơn checkout cũ.
  • Nếu branch đã chia sẻ với team, ưu tiên revert thay vì reset history.
  • Trước khi dùng lệnh mạnh, luôn chạy git status và đọc kỹ file sẽ bị ảnh hưởng.

Git reset revert restore là gì?

git reset, git revertgit restore đều giúp undo thay đổi, nhưng mỗi lệnh tác động vào một phần khác nhau của Git. Reset thường liên quan đến HEAD, index và history; revert tạo commit mới; restore tập trung vào file trong working tree hoặc staging area.

Tài liệu chính thức của Git có mục riêng “Reset, restore and revert” để phân biệt ba nhóm lệnh này [1]. Đây không chỉ là khác biệt tên gọi. Khi học git reset revert restore, bạn nên nhìn vào phạm vi tác động trước: file, staging area hay commit history.

Working tree
File thực tế bạn đang thấy và sửa trong thư mục dự án.
Index hoặc staging area
Vùng Git chuẩn bị nội dung cho commit kế tiếp.
History
Chuỗi commit đã được ghi lại trên branch.

Hiểu ba lớp này giúp bạn chọn lệnh chính xác hơn. Ví dụ: muốn bỏ file khỏi staging thì không cần đụng history; muốn đảo ngược commit đã push thì không nên xóa history; muốn lấy lại nội dung file từ commit cũ thì restore thường rõ nghĩa hơn.

Ba lớp Git working tree staging area và commit history
Ba lệnh undo tác động vào các lớp khác nhau trong Git.

So sánh nhanh reset, revert và restore

Cách nhớ nhanh: reset dùng khi muốn di chuyển lại trạng thái branch hoặc staging, revert dùng khi muốn tạo commit đảo ngược, restore dùng khi muốn khôi phục file. Với cụm git reset revert restore, nếu chỉ nhớ một nguyên tắc cho team, hãy nhớ: đã push lên branch chung thì ưu tiên revert.

LệnhTác động chínhDùng khi nàoRủi ro
git resetDi chuyển HEAD, cập nhật index hoặc working tree tùy modeUndo commit chưa push, bỏ stagingCó thể rewrite history hoặc mất thay đổi local nếu dùng --hard
git revertTạo commit mới đảo ngược commit cũUndo commit đã push hoặc branch chungCó thể conflict nếu code đã thay đổi nhiều
git restoreKhôi phục file trong working tree hoặc indexBỏ thay đổi file, unstage file, lấy file từ commit cũCó thể mất sửa đổi local nếu restore vào working tree

Atlassian cũng phân tích reset, checkout và revert theo tác động lên working directory, staged snapshot và commit history; cách nhìn theo từng lớp này rất hữu ích khi bạn cần chọn lệnh undo phù hợp [2].

Bảng so sánh git reset git revert git restore
So sánh theo tác động giúp bạn tránh dùng sai lệnh undo.

Khi nào nên dùng git reset?

Bạn nên dùng git reset khi muốn sửa commit chưa push, đưa branch local lùi về mốc cũ, hoặc bỏ file khỏi staging area. Reset mạnh nhất trong ba lệnh vì nó có thể thay đổi vị trí HEAD và history local.

Các mode thường gặp:

  • git reset --soft HEAD~1: lùi commit nhưng giữ thay đổi trong staging area.
  • git reset --mixed HEAD~1: lùi commit và đưa thay đổi về unstaged. Đây là mode mặc định.
  • git reset --hard HEAD~1: lùi commit và đưa working tree về trạng thái cũ, có thể làm mất thay đổi chưa lưu trong Git.

Tài liệu git reset mô tả reset theo các chế độ ảnh hưởng đến index và working tree [3]. Vì vậy, trước khi chạy --hard, hãy chắc chắn bạn không còn thay đổi local quan trọng.

git status
# Kiểm tra trước

git reset --soft HEAD~1
# Undo commit cuối nhưng giữ nội dung đã staged

git reset HEAD file.php
# Bỏ file khỏi staging area, không xóa nội dung file

Nếu bạn lỡ reset nhầm và commit biến mất khỏi git log, đừng hoảng. Bạn có thể dùng Git reflog để tìm lại mốc HEAD cũ.

So sánh git reset soft mixed hard
Reset có nhiều mode, khác nhau ở cách xử lý staging area và working tree.

Khi nào nên dùng git revert?

Bạn nên dùng git revert khi commit đã push hoặc branch đang được chia sẻ với người khác. Revert không xóa commit cũ, mà tạo một commit mới đảo ngược thay đổi, nên lịch sử vẫn minh bạch.

Ví dụ bạn đã push commit lỗi lên main:

git log --oneline -5
# abc1234 Thay đổi logic thanh toán

git revert abc1234
# Git tạo commit mới đảo ngược thay đổi của abc1234

git push origin main

Tài liệu git revert nêu rõ lệnh này ghi lại commit mới để đảo ngược một số commit trước đó [4]. Đây là lý do revert phù hợp với branch đã public: bạn không cần force push và team vẫn nhìn thấy vì sao thay đổi bị đảo ngược.

Revert vẫn có thể conflict nếu code hiện tại đã thay đổi nhiều so với thời điểm commit gốc. Khi đó bạn xử lý conflict, chạy git add, rồi tiếp tục revert. Nếu chưa chắc, dùng git revert --abort để quay lại trước thao tác.

Nếu lỗi của bạn là commit đúng nội dung nhưng sai branch, bài Git commit vào nhánh sai sẽ phù hợp hơn vì cần kết hợp cherry-pick, reset hoặc revert theo trạng thái đã push.

Git revert tạo commit mới để đảo ngược commit đã push
Revert giữ lịch sử rõ ràng khi bạn cần undo trên branch chung.

Khi nào nên dùng git restore?

Bạn nên dùng git restore khi muốn khôi phục file, bỏ thay đổi local hoặc bỏ file khỏi staging area mà không đụng commit history. Đây là lệnh rõ nghĩa hơn cho các thao tác trên file.

Tài liệu git restore mô tả lệnh này dùng để restore nội dung trong working tree hoặc index từ một source cụ thể [5]. Một vài lệnh hay dùng:

git restore app/Models/Order.php
# Bỏ thay đổi local của file, đưa file về trạng thái trong HEAD

git restore --staged app/Models/Order.php
# Bỏ file khỏi staging area nhưng giữ nội dung đã sửa

git restore --source=HEAD~1 app/Models/Order.php
# Lấy phiên bản file từ commit trước đó

Cẩn thận với lệnh đầu tiên: nếu bạn đã sửa file nhưng chưa commit, git restore file có thể làm mất phần sửa đó trong working tree. Nếu chưa chắc, hãy copy diff ra patch hoặc commit tạm trước.

Với lỗi “lỡ add nhầm”, dùng git restore --staged thường rõ nghĩa hơn git reset HEAD file. Còn nếu bạn đã commit nhầm file, xem thêm bài Git commit nhầm file để chọn amend, rm cached hoặc revert đúng tình huống.

Git restore khôi phục file và bỏ file khỏi staging area
Restore phù hợp với thao tác trên file hơn là chỉnh lịch sử commit.

Chọn lệnh theo tình huống thực tế

Nếu bạn chọn lệnh theo câu hỏi “mình muốn sửa file, sửa staging hay sửa history?”, quyết định sẽ dễ hơn nhiều. Dưới đây là các tình huống thường gặp trong dự án thật.

Tình huốngLệnh nên dùngVì sao
Lỡ git add .git restore --staged .Bỏ staging, giữ file local
Sửa file sai và muốn bỏ thay đổigit restore fileKhôi phục file từ HEAD
Commit cuối chưa push, muốn sửa lạigit reset --soft HEAD~1Undo commit nhưng giữ thay đổi để commit lại
Commit lỗi đã push lên maingit revert <hash>Tạo commit đảo ngược, không rewrite history
Muốn lấy lại một file từ commit cũgit restore --source=<hash> fileChỉ tác động vào file cần lấy
Lỡ reset hard mất commitgit reflogTìm lại mốc HEAD cũ trước khi recovery

GitHub Docs cũng khuyến nghị xử lý các lỗi non-fast-forward bằng cách tích hợp thay đổi remote trước khi push tiếp, thay vì cố đẩy lịch sử local đè lên remote [6]. Đây là tinh thần chung khi dùng Git trong team: tránh rewrite history đã chia sẻ nếu không có lý do rõ ràng. Vì vậy, khi so sánh git reset revert restore, yếu tố “đã push hay chưa” phải được đặt trước sự tiện tay.

Bạn đang đọc bài viết thuộc chuyên mục Lập trình của VietnamTutor — nơi mình chia sẻ các workflow thực chiến để developer xử lý lỗi trong dự án thật, không chỉ học lệnh rời rạc.

Checklist an toàn trước khi undo

Trước khi chạy reset, revert hoặc restore, hãy kiểm tra trạng thái repo và tạo đường lui nếu thao tác có rủi ro. Undo trong Git không khó, nhưng undo sai lệnh có thể làm vấn đề lớn hơn.

Checklist nhanh khi dùng git reset revert restore:

  • Chạy git status để xem working tree có clean không.
  • Chạy git log --oneline --decorate -5 để xác định commit cần xử lý.
  • Nếu định dùng reset --hard, tạo branch backup trước: git branch backup-before-reset.
  • Nếu commit đã push lên branch chung, ưu tiên git revert.
  • Nếu chỉ muốn sửa file hoặc staging area, ưu tiên git restore.
  • Sau khi undo, chạy test hoặc ít nhất kiểm tra diff bằng git diff.

Tóm lại, git reset revert restore không nên được chọn theo thói quen. Hãy chọn theo phạm vi tác động: file thì restore, commit đã publish thì revert, history local chưa push thì reset. Cách nghĩ này sẽ giúp bạn xử lý Git tự tin hơn và ít phải cứu hộ bằng reflog.

Nguồn tham khảo

  1. Git documentation: git
  2. Atlassian Git tutorial: Resetting, checking out and reverting
  3. Git documentation: git-reset
  4. Git documentation: git-revert
  5. Git documentation: git-restore
  6. GitHub Docs: Dealing with non-fast-forward errors

Các câu hỏi thường gặp

Git reset khác git revert thế nào?

git reset thường di chuyển HEAD hoặc branch pointer và có thể rewrite history local, còn git revert tạo commit mới để đảo ngược commit cũ. Với branch đã push, revert thường an toàn hơn.

Khi nào dùng git restore?

Dùng git restore khi bạn muốn khôi phục file, bỏ thay đổi local hoặc bỏ file khỏi staging area mà không cần chỉnh commit history.

Commit đã push rồi có nên dùng git reset không?

Không nên reset history đã push lên branch chung nếu team chưa thống nhất. Trong hầu hết trường hợp, dùng git revert sẽ an toàn và minh bạch hơn.

Git reset –hard có nguy hiểm không?

Có. git reset --hard có thể đưa working tree về trạng thái cũ và làm mất thay đổi chưa được commit. Trước khi dùng, hãy chạy git status và cân nhắc tạo branch backup.

Bỏ file khỏi staging nên dùng reset hay restore?

Cả git reset HEAD filegit restore --staged file đều có thể dùng. Với Git hiện đại, git restore --staged file rõ nghĩa hơn vì nó nói đúng mục tiêu là bỏ file khỏi staging area.

Bạn đang vướng một tình huống undo Git cụ thể? Hãy mô tả commit đã push chưa, branch có ai dùng chung không và bạn muốn giữ hay bỏ thay đổi nào; chỉ cần ba thông tin đó là chọn lệnh sẽ dễ hơn rất nhiều.

Tú Anh

Cây bút chính tại VietnamTutor

Bài viết cùng chuyên mục

Git commit vào nhánh sai: cách chuyển an toàn

Bài viết hướng dẫn xử lý git commit vào nhánh sai theo từng tình huống: commit chưa push, đã push, nhiều commit liên tiếp hoặc branch

TypeScript cho website doanh nghiệp: API, form và lỗi

TypeScript cho website doanh nghiệp đáng dùng khi bạn cần kiểm soát API contract, form schema, CMS payload và cấu hình môi trường. Bài này giúp

React Server Components performance: khi nào nên dùng?

React Server Components performance không phải phép màu. Bài này giúp bạn biết khi nào RSC giảm JavaScript thật, khi nào làm kiến trúc phức tạp

Git commit nhầm file: bỏ file khỏi commit an toàn

Bài viết hướng dẫn xử lý git commit nhầm file theo từng tình huống: chưa commit, đã commit chưa push, đã push lên remote, hoặc lỡ

Git reflog: khôi phục commit đã mất an toàn

Bài viết hướng dẫn dùng git reflog để khôi phục commit đã mất sau reset, rebase, amend hoặc xóa nhánh. Bạn sẽ biết cách đọc reflog,

Git pull bị conflict: cách sửa không mất code

Bài viết hướng dẫn cách xử lý git pull bị conflict theo từng bước: kiểm tra trạng thái, sửa file xung đột, test lại và hoàn

Next.js production performance: chọn SSR, SSG, ISR hay Edge

Bài viết giúp developer và tech lead chọn cách render phù hợp để tối ưu Next.js production performance mà không làm kiến trúc phức tạp quá

Nâng cấp Laravel 13: Checklist 10 bước cần kiểm tra

Hướng dẫn nâng cấp Laravel 13 chi tiết với checklist 10 bước. Từ kiểm tra PHP 8.3, cập nhật dependencies, đến xử lý lỗi thường gặp

Hardening Laravel production: Checklist bảo mật cần làm

Checklist hardening Laravel production toàn diện. Từ cấu hình server, database, SSL đến security headers, rate limiting và monitoring.

Authentication và authorization trong Laravel: Cách phân biệt

Hướng dẫn chi tiết cách xây dựng hệ thống Authentication (xác thực) và Authorization (phân quyền) trong Laravel với Breeze, Fortify, Sanctum, Policies và Gates.

Bảo mật Laravel: 10 lỗi phổ biến và cách phòng tránh

Hướng dẫn 10 lỗi bảo mật phổ biến nhất trong Laravel và cách phòng tránh hiệu quả. Từ XSS, SQL injection đến authentication vulnerabilities.

Migration PHP Attributes Laravel 13: Hướng Dẫn Chi Tiết

Cách chuyển đổi từ protected properties sang PHP Attributes trong Laravel 13 với hướng dẫn từng bước và code examples chi tiết.