Sau một lần reset hoặc rebase, commit vừa làm có thể không còn xuất hiện trong lịch sử của nhánh hiện tại. Điều đó chưa chắc có nghĩa dữ liệu đã bị xóa. Git reflog giúp tìm lại những vị trí mà tham chiếu từng trỏ tới trong repository local, từ đó xác định commit cần giữ.
1. Phân biệt lịch sử commit và reflog
git log thường cho bạn xem lịch sử đi từ commit hiện tại. Theo tài liệu git-reflog, reflog ghi nhận việc cập nhật các tham chiếu trong repository local; reflog của HEAD còn ghi lại việc chuyển nhánh. Vì vậy, nó có thể cung cấp manh mối về commit không còn nằm trên đường lịch sử bạn đang xem.
Đây không phải lịch sử dùng chung của cả nhóm và không được đồng bộ như commit qua push/pull. Hãy kiểm tra trên đúng bản sao repository nơi thao tác đã xảy ra.
2. Dừng thay đổi và ghi nhận hiện trạng
Quy trình dưới đây dành cho việc tìm commit đã tồn tại, không phải khôi phục mọi nội dung chưa commit. Trước tiên, tránh tiếp tục reset, dọn dữ liệu Git hoặc chạy công cụ “clean up” khi chưa hiểu sự cố.
git status --short
git reflog show HEAD -n 20
Lệnh đầu giúp nhận diện file đang sửa và file chưa được theo dõi. Bảo toàn công việc đó bằng phương án sao lưu phù hợp trước khi chuyển nhánh hoặc khôi phục file. Không dùng thao tác ghi đè để làm sạch thư mục cho tiện.
Trong reflog, đọc cả mã commit và mô tả hành động. Không mặc định dòng ngay trước dòng mới nhất là phiên bản đúng: giữa thời điểm cần tìm và hiện tại có thể đã có nhiều lần chuyển nhánh, commit hoặc rebase.
3. Xác minh commit ứng viên
Giả sử bạn thấy mã abc1234. Đây chỉ là mã minh họa; phải thay bằng mã thực tế từ repository của bạn:
git show --stat abc1234
git show abc1234 -- src/Example.php
git show giúp xem thông tin commit và thay đổi liên quan. Kiểm tra tác giả, thông điệp, danh sách file và nội dung cần tìm. Với commit merge, cách hiển thị diff có đặc điểm riêng; đừng kết luận chỉ từ việc không thấy một đoạn diff như kỳ vọng.
Để đọc toàn bộ một file tại commit đó mà không ghi đè file hiện tại:
git show abc1234:src/Example.php
Đường dẫn tính từ gốc repository và phải tồn tại tại commit đã chọn. Việc nhìn thấy đúng tên file chưa đủ; hãy kiểm tra cả phần sửa bạn thực sự cần.
4. Tạo nhánh cứu hộ trước khi tích hợp lại
git branch rescue/recovered-work abc1234
git log -1 --oneline rescue/recovered-work
git status --short
Theo tài liệu git-branch, tạo nhánh theo cách này không tự chuyển sang nhánh mới. Nó đặt một tên nhánh tại commit đã xác minh, không yêu cầu ghi đè working tree. Nếu tên đã tồn tại, chọn tên mới; không thêm tùy chọn ép ghi đè chỉ để vượt qua thông báo lỗi.
Đến đây, commit đã có nhánh để tham chiếu. Bước tiếp theo là quyết định cần lấy cả nhánh, một commit hay một phần thay đổi. Merge và cherry-pick có thể tạo xung đột; chỉ thực hiện sau khi bảo toàn phần việc hiện tại và xem xét quan hệ lịch sử. Không cần force-push để hoàn thành bước cứu hộ local.
5. Biết giới hạn để không chủ quan
- Reflog không phải bản sao lưu mọi lần gõ trong trình soạn thảo. Nội dung chưa được Git lưu thành đối tượng không thể trông chờ khôi phục bằng quy trình này.
- Mục reflog có thể hết hạn; các đối tượng không còn được giữ lại có thể bị dọn. Không có bảo đảm khôi phục vô thời hạn.
- Một bản clone mới không tự mang theo reflog local của bản clone cũ.
- Tìm được commit không chứng minh toàn bộ tính năng đã được phục hồi; vẫn cần kiểm thử trước khi bàn giao.
6. Checklist kết thúc
Hãy xác nhận ba việc: commit đúng đã có nhánh cứu hộ, phần sửa chưa commit vẫn được giữ, và phương án tích hợp đã được kiểm tra. Sau đó thực hiện quy trình review, kiểm thử và sao lưu của dự án. Giá trị của reflog nằm ở việc cung cấp một đường quay lại có thể kiểm chứng, không phải lời hứa rằng mọi thao tác Git đều có thể hoàn tác.




Chưa có bình luận. Hãy là người đầu tiên chia sẻ ý kiến.