Git reflog: cứu code khi lỡ tay reset --hard hoặc xóa nhầm nhánh

  • author-image

    Nguyễn Đình Cường

  • blog-tag
  • blog-comment 0 comment
  • created-date 09 Nov, 2026
blog-thumbnail

Bạn vừa chạy git reset --hard và thấy mấy ngày công việc biến mất? Hoặc xóa nhầm một nhánh chưa merge? Đừng vội hoảng. Git thường giữ lại nhiều hơn bạn nghĩ, và công cụ giúp bạn tìm lại chúng là git reflog. Đây có thể là lệnh cứu bạn nhiều lần nhất trong sự nghiệp.

Reflog là gì?

Reflog (reference log) là nhật ký cục bộ ghi lại mọi lần con trỏ HEAD và các nhánh di chuyển: mỗi commit, checkout, merge, rebase, reset... đều để lại một dòng. Khác với git log chỉ hiển thị lịch sử commit đi từ vị trí hiện tại, reflog hiển thị những nơi bạn đã từng đi qua, kể cả các commit giờ không còn thuộc nhánh nào.

Lưu ý quan trọng: reflog chỉ tồn tại trên máy của bạn, không được đẩy lên remote, và các mục chỉ được giữ trong một khoảng thời gian có hạn (mặc định vài tuần đến vài tháng, tùy loại và cấu hình) trước khi bị dọn.

Cách đọc reflog

git refloga1b2c3d (HEAD -> main) HEAD@{0}: reset: moving to HEAD~39f8e7d6 HEAD@{1}: commit: Thêm trang thanh toán5e4d3c2 HEAD@{2}: commit: Sửa lỗi giỏ hàng7a6b5c4 HEAD@{3}: commit: Thêm danh sách sản phẩm...

Mỗi dòng gồm mã commit, chỉ số dạng HEAD@{n} (n càng nhỏ càng gần hiện tại) và mô tả hành động. Trong ví dụ, dòng HEAD@{1} là trạng thái ngay trước khi bạn reset lùi 3 commit, chính là chỗ cần quay lại.

Tình huống 1: Lỡ reset --hard

  1. Chạy git reflog và tìm dòng ngay trước thao tác reset (ở ví dụ là 9f8e7d6).
  2. Quay về đó:
    git reset --hard 9f8e7d6
    hoặc dùng cú pháp git reset --hard HEAD@{1}.
  3. Kiểm tra bằng git log rằng các commit đã trở lại.

Tình huống 2: Xóa nhầm nhánh chưa merge

git branch -D feature/payment# Deleted branch feature/payment (was 9f8e7d6).

Thông báo cho bạn mã commit cuối của nhánh. Nếu không thấy, tìm trong reflog rồi tạo lại nhánh:

git branch feature/payment 9f8e7d6

Tình huống 3: Rebase hoặc amend làm hỏng lịch sử

Sau một lần rebase đầy xung đột mà kết quả sai, bạn muốn quay về trạng thái trước khi bắt đầu. Trong reflog, tìm dòng có nội dung kiểu rebase (start) hoặc dòng ngay trước nó, rồi:

git reset --hard HEAD@{5}   # thay số 5 bằng đúng chỉ số bạn tìm thấy

Với git commit --amend lỡ ghi đè commit cũ, commit trước amend vẫn nằm trong reflog.

Tình huống 4: Commit khi đang ở trạng thái detached HEAD

Bạn checkout một commit cụ thể, làm việc, commit, rồi chuyển sang nhánh khác. Các commit đó không thuộc nhánh nào nhưng vẫn có trong reflog. Tìm mã commit rồi tạo nhánh để giữ lại:

git switch -c cuu-code 3c2b1a0

Một cách an toàn hơn: xem trước khi quay lại

Trước khi reset cứng, bạn có thể xem commit cần khôi phục có đúng không:

git show 9f8e7d6git log --oneline 9f8e7d6 -5git switch -c thu-khoi-phuc 9f8e7d6   # tạo nhánh thử, không đụng nhánh hiện tại

Tạo nhánh mới tại commit đó là cách ít rủi ro nhất, bạn có thể kiểm tra rồi quyết định hợp nhất hoặc cherry-pick những gì cần.

Còn những gì reflog không cứu được?

  • Thay đổi chưa bao giờ được commit hoặc stash. Nếu bạn chạy reset --hard hoặc checkout -- khi chưa commit, các thay đổi đó không nằm trong reflog. Vì vậy hãy commit (hoặc stash) thường xuyên, kể cả commit tạm.
  • File bị xóa mà chưa từng add/commit.
  • Commit đã bị dọn dẹp sau thời hạn giữ của reflog và quá trình thu gom rác (garbage collection) của Git.
  • Công việc trên máy khác hoặc repo đã bị xóa hoàn toàn.

Một mẹo cứu hộ hiếm gặp: git fsck --lost-found có thể tìm thấy các đối tượng "mồ côi" chưa bị dọn, kể cả những tệp từng được git add nhưng chưa commit. Tuy nhiên kết quả khó đọc hơn, chỉ nên dùng khi thật sự cần.

Thói quen để ít phải cứu hộ

  1. Commit nhỏ và thường xuyên, dù chỉ là commit tạm; sau đó có thể dọn lại bằng rebase interactive.
  2. Đẩy nhánh làm việc lên remote để có bản sao lưu.
  3. Dùng git stash trước khi thử các lệnh có rủi ro.
  4. Đọc kỹ lệnh có --hard, -f, -D trước khi nhấn Enter, và chạy git status để biết mình sắp bỏ gì.
  5. Khi chưa chắc, tạo nhánh dự phòng: git branch backup-truoc-khi-rebase.

Kết luận

Git được thiết kế để khó mất dữ liệu đã commit. Nhớ rằng khi mọi thứ có vẻ biến mất, hãy dừng lại, chạy git reflog, tìm trạng thái trước đó và khôi phục bằng nhánh mới hoặc reset. Biết lệnh này giúp bạn tự tin thử nghiệm hơn với Git.

Nếu bạn muốn nắm vững Git cùng các tình huống thường gặp, hãy xem thêm khóa học tại codebem.com.

author_photo
Nguyễn Đình Cường

0 comment