Bạn sửa một file, đưa một phần thay đổi vào staging rồi sửa tiếp. Khi muốn bỏ lần sửa cuối, câu hỏi quan trọng không chỉ là “dùng lệnh nào”, mà là “muốn lấy lại phiên bản nào”. Git restore cho phép chọn nguồn và nơi nhận dữ liệu; nhầm hai yếu tố này có thể làm mất công việc chưa lưu.
1. Xác định ba phiên bản trước khi thao tác
Hướng dẫn này áp dụng cho repository đã có commit, file được Git theo dõi và không đang xử lý merge conflict. Giả sử file src/Example.php có ba phiên bản: A trong HEAD, B trong index sau khi git add, và C trong working tree sau lần sửa tiếp theo.
- HEAD: nội dung thuộc commit hiện tại.
- Index, hay staging area: nội dung đang chuẩn bị cho commit tiếp theo.
- Working tree: nội dung file đang nằm trong thư mục làm việc.
Đừng coi B và C là cùng một phiên bản chỉ vì chúng có chung tên file. Một lần add trước đó không tự đưa các chỉnh sửa tiếp theo vào staging.
2. Đọc trạng thái và diff trước
git status --short
git diff -- src/Example.php
git diff --cached -- src/Example.php
Trong tình huống A–B–C, diff đầu cho thấy khác biệt giữa B và C; diff có --cached cho thấy khác biệt giữa A và B. Các lệnh này dùng để kiểm tra, không khôi phục hay xóa nội dung.
Thay đường dẫn minh họa bằng file thật. Trước lệnh ghi bên dưới, hãy sao lưu độc lập mọi nội dung còn cần, kể cả phiên bản đã stage nếu muốn giữ nó riêng. Bản sao working tree chỉ giữ C, không tự lưu riêng B. Kiểm tra bản sao đọc được trước khi tiếp tục.
3. Chọn đúng nguồn và đích
Theo tài liệu Git restore, khi không chỉ định nguồn, lệnh thông thường lấy từ index; nếu có --staged, nguồn mặc định là HEAD. Bảng dưới giả định file tồn tại ở cả ba nơi và mỗi hàng được xét độc lập từ trạng thái A–B–C.
| Lệnh | Index sau lệnh | Working tree sau lệnh |
|---|---|---|
| git restore -- src/Example.php | B | B |
| git restore --staged -- src/Example.php | A | C |
| git restore --source=HEAD --worktree -- src/Example.php | B | A |
Cảnh báo: hàng thứ nhất và thứ ba ghi đè working tree, có thể làm mất chỉnh sửa chưa commit. Hàng thứ hai giữ file đang sửa nhưng thay nội dung index. Đây là các lựa chọn khác nhau, không phải ba bước cần chạy liên tiếp.
Dấu -- phân tách phần tùy chọn và đường dẫn. Trong lần làm quen đầu tiên, chỉ chọn một file cụ thể; không thay bằng dấu chấm hay mẫu khớp cả thư mục để làm nhanh.
4. Tình huống nào dùng lựa chọn nào?
Nếu B là phiên bản bạn đã kiểm tra và C là thử nghiệm không muốn giữ, lấy từ index về working tree có thể phù hợp sau khi sao lưu. Nếu chỉ muốn bỏ stage để chia lại commit, dùng --staged và giữ C để tiếp tục làm việc.
Nếu muốn xem nội dung commit hiện tại, hãy đọc trước bằng git show HEAD:src/Example.php; chưa cần ghi đè file. Chỉ chọn --source=HEAD --worktree khi thực sự muốn working tree trở thành A và đã chấp nhận thay thế nội dung hiện có.
5. Kiểm tra lại và biết giới hạn
Chạy lại status cùng hai lệnh diff, đọc file và chạy kiểm thử liên quan. Đừng suy ra đã đúng chỉ vì lệnh restore không báo lỗi: có thể bạn chọn đúng cú pháp nhưng sai phiên bản mong muốn.
Nếu đường dẫn được theo dõi không tồn tại trong nguồn khôi phục, restore có thể xóa nó để khớp nguồn. File mới chưa từng được Git ghi nhận cũng không có sẵn phiên bản để lấy lại từ HEAD. Không coi reflog là bản sao lưu chắc chắn cho nội dung chưa commit.
Nguyên tắc ngắn gọn: xác định nguồn, xác định đích, bảo toàn phần còn cần rồi mới khôi phục một đường dẫn cụ thể. Git restore hữu ích nhất khi bạn biết rõ phiên bản nào đang được thay thế.




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