Quay lại trạng thái trước của Git Repository

Thỉnh thoảng, một vài dự án, do điều chỉnh quá đà, cái cục cốt (code) của mình nó tung toé. Mà giờ già rồi, không như ngày xưa, nhớ được tất cả. Chưa kể đang coding lại làm ván game, vào một lệnh nuôi con coin, ra ngoài ban công tưới cái cây, đến lúc ngồi lại bàn chả nhớ ra mình đang làm gì cả. 🤣

Sau khi pha cốc cà phê, ngồi nhâm nhi rồi sắp xếp lại toàn bộ quá trình vừa rồi trong đầu, mình quyết định reset toàn bộ để quay lại trạng thái ổn định gần nhất của dự án 🫣 và đây là quá trình 😊

Cảnh báo: Bài viết thuần tuý kỹ thuật, lẫn lộn giữa thuật ngữ và chọc cười, tiếng anh cùng tiếng việt, đọc dễ buồn ngủ.

Tình huống này hoá ra lại khá phổ biến, rất nhiều người sau chỉnh sửa sai tập tin hoặc muốn loại bỏ toàn bộ thay đổi và đang trong tình trạng rối tung rối mù, và rồi lúc đó chỉ muốn ước gì mình chưa bắt đầu. Và đây là hướng dẫn bạn cần.

Trước khi bắt đầu, luôn kiểm tra trạng thái repository bằng lệnh:

git status

Điều này giúp bạn xác nhận các thay đổi đang tồn tại, bao gồm file đã chỉnh sửa (modified), file đã staged, và file untracked (mới tạo chưa theo dõi).

1. Reset Tập Tin Cụ Thể Về Trạng Thái Commit Gần Nhất

Nếu bạn chỉ muốn hủy thay đổi trên một hoặc vài tập tin cụ thể mà không ảnh hưởng đến toàn bộ repository, hãy sử dụng các lệnh sau. Các lệnh này chỉ discard thay đổi cục bộ, không thay đổi lịch sử commit.

Sử dụng git checkout (Phù hợp với mọi phiên bản Git):

  • Bước 1: Xác định tập tin cần reset từ git status.
  • Bước 2: Chạy lệnh git checkout -- <tập_tin> để khôi phục tập tin về trạng thái HEAD. Thay <tập_tin> bằng đường dẫn thực tế (ví dụ: src/main.py).
    Nếu muốn reset nhiều tập tin cùng lúc, liệt kê chúng: git checkout -- file1.txt file2.txt.
    Để reset tất cả tập tin đã thay đổi trong thư mục hiện tại: git checkout ..
  • Bước 3: Kiểm tra lại với git status để đảm bảo thay đổi đã bị hủy.

Lưu ý: Lệnh này chỉ ảnh hưởng đến file tracked (đã commit trước đó). Nếu file đã staged (add vào staging), cần unstage trước (xem phần reset nếu staged bên dưới).

Sử dụng git restore (Dành cho Git phiên bản 2.23 trở lên, rõ ràng hơn):

  • Bước 1: Kiểm tra trạng thái như trên.
  • Bước 2: Chạy lệnh: git restore <tập_tin>. Để restore tất cả: git restore ..
  • Bước 3: Xác nhận với git status.

Ưu điểm: Lệnh này được thiết kế riêng cho việc khôi phục, tránh nhầm lẫn với các chức năng khác của git checkout.

Nếu Tập Tin Đã Staged (Đã Add Vào Staging Area):

  • Bước 1: Unstage tập tin trước: git reset HEAD <tập_tin>
  • Bước 2: Sau đó discard thay đổi bằng git checkout -- <tập_tin> hoặc git restore <tập_tin>.
  • Bước 3: Kiểm tra git status để thấy tập tin quay về trạng thái unmodified.

2. Reset Toàn Bộ Repository Về Trạng Thái Commit Gần Nhất

Nếu bạn muốn loại bỏ toàn bộ thay đổi, bao gồm tất cả file tracked, staged, và thậm chí untracked, để repository giống như vừa clone mới, hãy kết hợp git reset --hardgit clean. Đây là cách mạnh mẽ, xóa vĩnh viễn mọi thứ chưa commit.

  • Sử dụng git reset --hard Để Reset File Tracked:
    • Bước 1: Kiểm tra trạng thái với git status.
    • Bước 2: Chạy lệnh để reset toàn bộ về HEAD: git reset --hard HEAD
    • Lệnh này sẽ xóa mọi thay đổi trong working directory và staging area cho tất cả file tracked.
    • Bước 3: Kiểm tra lại git status – bây giờ không còn thay đổi tracked.

Sử dụng git clean Để Xóa File Untracked:

  • Bước 1: Xem trước những gì sẽ bị xóa (dry run để tránh mất dữ liệu): git clean -n -d
    • -n: Chỉ hiển thị, không xóa.
    • -d: Bao gồm thư mục untracked.
  • Bước 2: Nếu chắc chắn, xóa thực sự: git clean -f -d
    • -f: Buộc xóa.
    • Nếu muốn xóa cả file bị ignore (theo .gitignore), thêm -x: git clean -f -d -x. Nhưng hãy cẩn thận vì có thể xóa file quan trọng như thư mục build hoặc config.
  • Bước 3: Kiểm tra git status – repository giờ sạch sẽ như clone mới.

3. Giữ Lại Trạng Thái Hiện Tại Nếu Cần (Sử Dụng Git Stash)

Nếu bạn chưa chắc chắn muốn xóa vĩnh viễn thay đổi mà chỉ tạm thời reset để kiểm tra hoặc làm việc khác, hãy sử dụng git stash để lưu trữ thay đổi cục bộ. Sau đó, bạn có thể apply lại nếu cần.

  • Bước 1: Lưu Trạng Thái Hiện Tại: git stash push -m "Lưu thay đổi tạm thời"
    • -m: Thêm mô tả để dễ nhận biết sau.
    • Lệnh này sẽ lưu tất cả thay đổi (tracked và staged) vào một stash, và reset working directory về trạng thái HEAD.
  • Bước 2: Kiểm Tra Stash: git stash list. Bạn sẽ thấy danh sách stash, ví dụ: stash@{0}: On main: Lưu thay đổi tạm thời.
  • Bước 3: Apply Lại Nếu Cần:
    • Để apply stash mới nhất và giữ nguyên stash: git stash apply
    • Để apply và xóa stash: git stash pop. Nếu có nhiều stash, chỉ định ID: git stash apply stash@{0}.
  • Bước 4: Nếu Muốn Xóa Stash: git stash drop stash@{0}. Hoặc xóa tất cả: git stash clear.

Sử dụng stash giúp bạn linh hoạt: reset tạm thời mà vẫn giữ thay đổi để quay lại sau.

Lưu Ý Quan Trọng Khi Reset

  • Rủi Ro Mất Dữ Liệu: Các lệnh reset và clean xóa vĩnh viễn thay đổi chưa commit. Luôn sao lưu (copy thư mục) hoặc dùng stash trước nếu nghi ngờ.
  • Chỉ Ảnh Hưởng Cục Bộ: Không thay đổi remote repository. Nếu cần đồng bộ, chạy git pull sau reset. Nếu đã push thay đổi sai, có thể cần git push --force (nhưng tránh nếu làm việc nhóm).
  • Reset Từ Commit Cụ Thể: Nếu không phải commit gần nhất, thay HEAD bằng hash (tìm qua git log): git reset --hard <hash>.
  • Tránh Lạm Dụng: Không dùng git reset --hard nếu đang ở giữa merge hoặc rebase, vì có thể gây xung đột.
  • Lỗi Phổ Biến: Nếu gặp lỗi như “not a git repository”, đảm bảo bạn đang ở đúng thư mục repo. Nếu file untracked không xóa được, kiểm tra quyền truy cập file.
  • Làm Việc Nhóm: Thông báo đồng đội trước khi reset, đặc biệt nếu ảnh hưởng đến branch shared.

Nhìn có vẻ nhiều, nhưng thực ra chỉ vài lệnh mà thôi, và cũng bạn cũng chỉ cần nhớ một vài lệnh chính chứ chả mấy khi dùng hết đám lệnh này đâu. Phần lớn, ai cũng muốn reset mà không muốn quay lại để gỡ đám rối bùi bạn vừa bày ra làm gì cả.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.