Reflog: khôi phục commit tưởng đã mất
Reflog: Recovering Commits You Thought Were Lost
Lỡ tay git reset --hard và mất hết commit? Rebase hỏng làm biến mất công sức cả buổi? Thường thì chưa mất thật. Reflog là nhật ký riêng tư ghi lại mọi nơi HEAD từng đi qua, và là phao cứu sinh quan trọng nhất của Git.
Reflog là gì
Mỗi khi HEAD dịch chuyển — do commit, checkout, reset, merge hay rebase — Git ghi một dòng vào reflog. Đây là lịch sử cục bộ trên máy bạn, không bị push lên remote.
git reflog
Kết quả có dạng:
9f3a1c2 HEAD@{0}: reset: moving to HEAD~3
a1b2c3d HEAD@{1}: commit: add validation
e4f5g6h HEAD@{2}: commit: add login form
Mỗi mục có một tham chiếu HEAD@{n} để bạn quay lại đúng thời điểm đó.
Vì sao commit "biến mất" vẫn còn
Khi bạn reset --hard, các commit cũ không bị xóa ngay — chúng chỉ không còn nhánh nào trỏ tới (gọi là commit mồ côi dangling commit). Git giữ chúng một thời gian (mặc định ~30-90 ngày) trước khi dọn rác garbage collection. Trong khoảng đó, reflog vẫn nhớ hash của chúng nên bạn khôi phục được.
Khôi phục sau reset --hard
# Lỡ tay xóa 3 commit gần nhất:
git reset --hard HEAD~3
# Xem reflog tìm trạng thái trước khi reset:
git reflog
# a1b2c3d HEAD@{1}: commit: add validation <- điểm cần về
# Khôi phục:
git reset --hard a1b2c3d
# hoặc dùng tham chiếu reflog:
git reset --hard HEAD@{1}
Khôi phục branch đã xóa hoặc rebase hỏng
| Tình huống | Cách khôi phục |
|---|---|
Xóa nhầm nhánh (git branch -D) | Tìm hash cuối của nhánh trong reflog rồi git branch <ten> <hash> |
| Rebase hỏng | Tìm HEAD@{n} ngay trước lúc rebase, git reset --hard HEAD@{n} |
| Mất commit sau amend | git reflog để lấy hash commit cũ trước khi amend |
# Tạo lại nhánh đã xóa từ hash tìm được trong reflog
git branch feature-login a1b2c3d
Phản xạ khi hoảng
Trước khi làm gì khác, hãy chạy git reflog ngay. Đừng tiếp tục commit hay reset lung tung vì điều đó chỉ làm reflog dài thêm và khó tìm. Bình tĩnh đọc reflog, xác định HEAD@{n} đúng.
Reflog là cục bộ và có thời hạn
Reflog không được clone hay push — nó chỉ tồn tại trên máy bạn. Commit mồ côi cũng sẽ bị garbage collection dọn sau một thời gian. Đừng coi reflog là backup lâu dài.
Trọng tâm thi
Khi đề hỏi cách khôi phục commit/branch sau reset --hard hoặc rebase hỏng, đáp án là git reflog để tìm hash rồi git reset --hard <hash> hoặc git branch <ten> <hash>. Reflog là lịch sử dịch chuyển HEAD, cục bộ và có thời hạn.
Tóm tắt
git reflogghi lại mọi lầnHEADdịch chuyển: commit, reset, checkout, rebase...- Commit sau
reset --hardthành mồ côi nhưng còn tồn tại tới khi bị garbage collection. - Khôi phục: tìm hash/
HEAD@{n}trong reflog rồigit reset --hardhoặcgit branchđể dựng lại. - Reflog cứu được cả nhánh xóa nhầm và rebase hỏng.
- Reflog là cục bộ, không push, có thời hạn — là phao cứu sinh chứ không phải backup.