TẤT CẢ Git reset, revert và khôi phục sự cố (nâng cao)

Git reset, revert và khôi phục sự cố (nâng cao)

SEO 100/100 A+

📚 Git & GitHub Series (Bài 12/15) — Sau bộ phao cứu sinh stash, cherry-pick, reflog ở Bài 11, bài này dạy cách quay ngược thời gian có chủ đích với git reset và revert.

Git reset, revertrestore là ba cách "hoàn tác" trong Git, nhưng chúng hoạt động rất khác nhau — và nhầm lẫn giữa chúng có thể khiến bạn mất việc hoặc làm rối nhánh chung. Bài này phân biệt rõ từng lệnh, kèm quy tắc chọn lệnh nào trong từng tình huống, để bạn xử lý sự cố một cách an toàn.

Ba cấp độ của git reset

git reset di chuyển con trỏ nhánh về một commit trước đó. Điểm khác biệt nằm ở việc nó xử lý staging và working directory ra sao. Theo tài liệu git reset, có ba chế độ:

Chế độLùi commit?Giữ ở staging?Giữ ở working dir?
--soft
--mixed (mặc định)Không
--hardKhôngKhông (xóa hết)

Ví dụ gộp 3 commit cuối thành một cách thủ công:

git reset --soft HEAD~3
git commit -m "Gộp 3 commit thành một"

--soft lùi con trỏ nhưng giữ mọi thay đổi ở staging, sẵn sàng commit lại.

⚠️ Cẩn thận với git reset --hard

git reset --hard HEAD~1

Lệnh này lùi một commit và xóa sạch mọi thay đổi chưa commit. Nó cực mạnh nhưng nguy hiểm. Trước khi --hard, hãy chắc chắn bạn không cần các thay đổi hiện tại — hoặc đã git stash chúng. Nếu lỡ tay, nhớ tới git reflog ở Bài 11 để cứu hộ.

git revert — hoàn tác an toàn cho nhánh chung

Khác với reset (viết lại lịch sử), git revert tạo một commit mới đảo ngược thay đổi của một commit cũ:

git revert a1b2c3d

Vì không xóa lịch sử, revert an toàn cho nhánh đã chia sẻ như main. Đây là cách đúng để hoàn tác một thay đổi đã được push và người khác đã pull. Quy tắc:

  • Nhánh riêng, chưa chia sẻ → có thể reset.
  • Nhánh chung, đã push → dùng revert.

git restore — khôi phục file cụ thể

Từ Git 2.23, git restore chuyên dùng để khôi phục file (tách khỏi checkout cho rõ nghĩa):

git restore ten-file.txt          # bỏ thay đổi chưa staging
git restore --staged ten-file.txt # bỏ staging, giữ thay đổi

Đây là cách an toàn để "vứt" thay đổi một file về trạng thái commit gần nhất mà không đụng các file khác.

Bảng chọn lệnh theo tình huống

Tình huốngLệnh nên dùng
Sửa thông điệp commit cuốigit commit --amend
Bỏ staging một filegit restore --staged <file>
Vứt thay đổi chưa commit của filegit restore <file>
Lùi commit nhưng giữ thay đổigit reset --soft/--mixed
Hoàn tác commit đã push lên maingit revert
Quay về điểm cũ, chấp nhận mấtgit reset --hard (cẩn thận)

git commit --amend — sửa commit vừa tạo

Lỡ commit thiếu file hoặc sai chính tả thông điệp? Không cần tạo commit mới:

git add file-quen.txt
git commit --amend

Lưu ý --amend cũng viết lại lịch sử, nên đừng amend commit đã push lên nhánh chung.

Quy trình khôi phục an toàn khi gặp sự cố

Khi có chuyện không mong muốn, đừng vội gõ lệnh "mạnh tay". Hãy theo trình tự bình tĩnh sau:

  1. Dừng lại và git status — hiểu rõ Git đang ở trạng thái nào trước khi hành động.
  2. git log --onelinegit reflog — xác định commit bạn muốn quay về.
  3. Ưu tiên thao tác không phá hủy: thử git restore hoặc git revert trước khi nghĩ tới reset --hard.
  4. Sao lưu nhánh hiện tại bằng git switch -c backup-truoc-khi-sua để có đường lùi.
  5. Chỉ khi đã chắc chắn mới dùng lệnh viết lại lịch sử.

Thói quen "tạo nhánh sao lưu trước khi làm điều nguy hiểm" là dấu hiệu của người dùng Git cẩn trọng — nó biến mọi thao tác rủi ro thành có thể đảo ngược.

Tóm lại

Git reset lùi con trỏ và (tùy chế độ) xử lý thay đổi; revert hoàn tác an toàn bằng commit mới cho nhánh chung; restore khôi phục từng file. Quy tắc cốt lõi: viết lại lịch sử (reset, amend) chỉ cho nhánh riêng; nhánh chung thì revert. Nắm điều này, bạn xử lý sự cố mà không gây họa cho cả nhóm.

Bài 13, chúng ta nâng tầm lên quy trình tổ chức công việc: Git workflow chuyên nghiệp với Git Flow và GitHub Flow.

Tham khảo & Nguồn dữ liệu

1. Liên kết bên ngoài được sử dụng trong bài viết

2. Liên kết nội bộ liên quan

3. Bản quyền & Ghi nguồn

Một phần dữ liệu trong bài viết được tham khảo từ tài liệu git reset. Mọi thương hiệu, tên sản phẩm và tài liệu gốc thuộc quyền sở hữu của chủ sở hữu tương ứng. Bài viết chỉ trích dẫn, tổng hợp và phân tích — không nhằm thay thế tài liệu chính thức.

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

git reset và git revert khác nhau thế nào?
git reset di chuyển con trỏ nhánh về commit cũ, viết lại lịch sử — phù hợp cho nhánh riêng. git revert tạo một commit mới đảo ngược thay đổi của commit cũ, giữ nguyên lịch sử — an toàn cho nhánh chung.
git reset --soft, --mixed, --hard khác gì nhau?
--soft: lùi commit nhưng giữ thay đổi ở staging. --mixed (mặc định): lùi commit, giữ thay đổi ở working directory nhưng bỏ staging. --hard: lùi commit và XÓA mọi thay đổi — nguy hiểm, dùng cẩn thận.
Lỡ git reset --hard thì khôi phục được không?
Thường là được, nếu các commit đã từng được tạo. Dùng git reflog để tìm mã băm trước khi reset rồi git reset --hard tới mã đó. Nhưng thay đổi chưa từng commit thì không cứu được.

💬 BÌNH LUẬN

Đăng nhập GitHub để comment. Hỗ trợ markdown, reaction, reply.

S-DNA · CI/CD Monitor

Live TheoDoi8

🔄 running
theodoi8@github-actions

Đang tải terminal theodoi8…