TL;DR
- Bản chất: Dữ liệu trong Git di chuyển qua 4 vùng lưu trữ: Working Directory (Đĩa cứng), Staging Area / Index (Vùng đệm), Local Repository (Lịch sử commit / HEAD), và Remote Repository.
- Mục đích: Tách biệt giữa trạng thái soạn thảo nháp, chuẩn bị gói commit, và lưu trữ snapshot vĩnh viễn.
- Điểm mấu chốt:
git resetbản chất chỉ là lệnh di chuyển con trỏ HEAD lùi lại trên đồ thị commit; các cờ--soft,--mixed,--hardchỉ quyết định việc có kéo Staging Area và Working Directory lùi theo hay không. Mọi bước nhảy con trỏ đều được ghi lại tronggit reflog, tạo thành mạng lưới cứu hộ tuyệt đối.
Core Concept
1. Mô hình 4 Vùng Trạng thái (The 4 Zones)
[ Working Directory ] ──(git add)──> [ Staging Area (Index) ] ──(git commit)──> [ Local Repo (HEAD) ] ──(git push)──> [ Remote Repo ]
^ │ │
└───────── (git checkout/restore) ─────┴──────────── (git reset) ────────────────┘
- Working Directory (Thư mục làm việc): Các tập tin vật lý thực tế trên ổ cứng của bạn.
- Staging Area / Index (Vùng đệm): Ảnh chụp nháp nhị phân (
.git/index) chuẩn bị cho lần commit kế tiếp. - Local Repository (Kho lưu trữ cục bộ): Cơ sở dữ liệu đồ thị DAG chứa toàn bộ các commit snapshot đã xác nhận, quản lý bởi con trỏ
HEAD. - Remote Repository (Kho lưu trữ từ xa): Máy chủ GitHub/GitLab đồng bộ các tham chiếu qua mạng.
Practical Implementation
1. Phân biệt Bản chất: git reset --soft vs --mixed vs --hard
Bản chất của git reset HEAD~1 là: Di chuyển con trỏ HEAD lùi về commit trước đó 1 bước. Sự khác biệt nằm ở cách xử lý 2 vùng còn lại:
| Cờ lệnh Reset | Con trỏ HEAD | Staging Area (Index) | Working Directory (File đĩa) | Mục đích sử dụng điển hình |
|---|---|---|---|---|
--soft | Di chuyển lùi | GIỮ NGUYÊN (Code vẫn ở Staged) | GIỮ NGUYÊN | Gộp nhiều commit nhỏ lại thành 1 (Squash) trước khi commit lại. |
--mixed (Mặc định) | Di chuyển lùi | BỊ RESET (Unstaged) | GIỮ NGUYÊN | Huỷ commit cũ, đưa toàn bộ thay đổi về dạng Unstaged để phân loại lại. |
--hard | Di chuyển lùi | BỊ RESET | BỊ XÓA SỔ (Ghi đè bằng commit đích) | HỦY DIỆT: Xóa bỏ toàn bộ thay đổi rác không muốn giữ lại. |
Cơ chế An toàn & Ranh giới Hủy diệt của
git reset --hard:
- Đối với Untracked Files (File mới chưa từng
git add):git reset --hardKHÔNG chạm vào và KHÔNG xóa các file này. Chúng vẫn nằm nguyên trên ổ cứng (chỉ lệnhgit clean -fmới xóa).- Đối với Tracked Files (File đã được Git theo dõi từ trước): Mọi sửa đổi chưa commit trên các file này sẽ bị ghi đè và xóa sổ vĩnh viễn, không thể cứu lại bằng
git reflog.- Đối với Commits đã tạo: Dù bị
--hardlùi lại bao nhiêu bước, commit cũ vẫn nằm trong Object Store và được cứu lại 100% quagit reflog.
2. Cứu hộ Dữ liệu Thảm họa bằng git reflog
- Bản chất
git reflog: Là nhật ký cục bộ ghi lại mọi thao tác thay đổi vị trí của con trỏ HEAD (commit, checkout, rebase, reset). - Nguyên lý bất biến: Khi bạn
git reset --hardlàm mất commit, nút commit cũ không bị xóa khỏi ổ cứng ngay lập tức, mà chỉ bị biến thành commit mồ côi (Unreachable commit) và được giữ lại ít nhất 30 ngày trước khigit gcdọn dẹp.
Quy trình Phục hồi Commit Bị Xóa Nhầm
# 1. Xem lại nhật ký di chuyển của con trỏ HEAD
git reflog
# Output mẫu:
# 1a2b3c4 HEAD@{0}: reset: moving to HEAD~1 <-- Vừa lỡ tay reset nhầm
# 5d6e7f8 HEAD@{1}: commit: Important Feature Logic <-- Commit bị mất cần lấy lại
# 2. Tạo một nhánh mới khôi phục ngay tại vị trí commit bị mất
git checkout -b rescue-branch 5d6e7f8
# Kết quả: Toàn bộ code quan trọng được khôi phục 100%!