Git Four Zones and Reset Lifecycle

Tran Van Ngoc|

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 reset bả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, --hard chỉ 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 trong git 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) ────────────────┘
  1. 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.
  2. 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.
  3. 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.
  4. 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 ResetCon trỏ HEADStaging Area (Index)Working Directory (File đĩa)Mục đích sử dụng điển hình
--softDi chuyển lùiGIỮ NGUYÊN (Code vẫn ở Staged)GIỮ NGUYÊNGộ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ùiBỊ RESET (Unstaged)GIỮ NGUYÊNHuỷ commit cũ, đưa toàn bộ thay đổi về dạng Unstaged để phân loại lại.
--hardDi chuyển lùiBỊ RESETBỊ 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:

  1. Đối với Untracked Files (File mới chưa từng git add): git reset --hard KHÔ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ệnh git clean -f mới xóa).
  2. Đố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.
  3. Đối với Commits đã tạo: Dù bị --hard lùi lại bao nhiêu bước, commit cũ vẫn nằm trong Object Store và được cứu lại 100% qua git 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 --hard là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 khi git gc dọ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%!