git reflog lưu lại MỌI thay đổi của HEAD trong ~90 ngày (mặc định), kể cả các commit "đã mất".
Quy trình recover:
git reflog
# Output:
# abc123 HEAD@{0}: reset: moving to HEAD~3
# def456 HEAD@{1}: commit: feat: add payment service
# ghi789 HEAD@{2}: commit: feat: add cart logic
# jkl012 HEAD@{3}: commit: feat: add product modelTìm hash của commit cuối cùng trước khi reset, rồi:
# Recover tất cả 3 commits:
git reset --hard def456
# Hoặc cherry-pick từng commit:
git cherry-pick jkl012 ghi789 def456Ví dụ: mất 3 commit liên tiếp — dùng git reset --hard def456 (hash của commit cuối trước khi reset, tức HEAD@{1} trong ví dụ trên). Không dùng HEAD@{4} vì sẽ đi xa hơn cần thiết.
Lưu ý:
- reflog chỉ tồn tại trong local repo — clone lại từ remote sẽ KHÔNG có. Phải recover trên máy đã reset.
- git gc chạy định kỳ có thể xóa unreachable commit sau thời gian ngắn. Recover sớm.
- Stash bị mất: git fsck --lost-found rồi tìm dangling commit.
Phòng tránh: trước khi reset --hard luôn tạo backup branch: git branch backup/safe-point.
git reflog records EVERY HEAD change for ~90 days (default), including "lost" commits.
Recovery workflow:
git reflog
# Output:
# abc123 HEAD@{0}: reset: moving to HEAD~3
# def456 HEAD@{1}: commit: feat: add payment service
# ghi789 HEAD@{2}: commit: feat: add cart logic
# jkl012 HEAD@{3}: commit: feat: add product modelFind the hash of the last commit before the reset, then:
# Recover all 3 commits:
git reset --hard def456
# Or cherry-pick individual commits:
git cherry-pick jkl012 ghi789 def456Example: lost 3 consecutive commits — use git reset --hard def456 (the hash of the last commit before the reset, which is HEAD@{1} in the example above). Do not use HEAD@{4} — that would go further back than needed.
Warnings:
- reflog exists ONLY in the local repo — re-cloning from remote will NOT have it. Must recover on the machine that did the reset.
- Periodic git gc may purge unreachable commits. Recover early.
- Lost stashes: git fsck --lost-found then find dangling commits.
Prevention: before reset --hard, always create a backup branch: git branch backup/safe-point.