Giao diện
Thực hành: Git Internals Deep Dive
🎯 Mục tiêu
🎯 Sau bài thực hành này, bạn sẽ:
- Hiểu 4 loại object trong Git: blob, tree, commit, tag
- Biết cách SHA-1 hash được tính và tại sao nó đảm bảo tính toàn vẹn
- Khám phá cấu trúc bên trong
.git/directory bằng plumbing commands - Hiểu refs, HEAD, và cách Git thực sự hoạt động dưới lớp porcelain
Phần 1: Trắc nghiệm
🧠 Quiz
Câu 1: Mối quan hệ giữa các Git objects là gì?
- [ ] A) blob chứa tree, tree chứa commit
- [x] B) commit trỏ đến tree, tree trỏ đến blobs và trees con, blob chứa nội dung file
- [ ] C) Tất cả objects đều độc lập, không liên kết với nhau
- [ ] D) commit chứa trực tiếp nội dung file, không cần blob
💡 Giải thích: Git dùng mô hình phân cấp: commit ghi lại metadata (author, message, parent) và trỏ đến một tree đại diện cho trạng thái thư mục gốc. Tree chứa danh sách entries — mỗi entry trỏ đến blob (file) hoặc tree con (thư mục). Blob chỉ lưu nội dung file, không lưu tên file.
🧠 Quiz
Câu 2: SHA-1 hash trong Git được tính từ đâu?
- [ ] A) Chỉ từ nội dung file
- [ ] B) Từ tên file và đường dẫn
- [x] C) Từ header (loại object + kích thước) ghép với nội dung object
- [ ] D) Từ timestamp khi object được tạo
💡 Giải thích: Git tính SHA-1 bằng công thức:
SHA1("<type> <size>\0<content>"). Ví dụ một blob:SHA1("blob 13\0Hello World\n"). Điều này có nghĩa: cùng nội dung luôn cho cùng hash (content-addressable storage), và bất kỳ thay đổi nào — dù 1 byte — tạo hash hoàn toàn khác.
🧠 Quiz
Câu 3: File .git/HEAD chứa gì?
- [ ] A) SHA-1 hash của commit đầu tiên trong repository
- [ ] B) Danh sách tất cả các branch
- [x] C) Reference đến branch hiện tại (ví dụ
ref: refs/heads/main) hoặc trực tiếp một commit SHA - [ ] D) Nội dung của file mới nhất được commit
💡 Giải thích: Thông thường HEAD chứa symbolic reference:
ref: refs/heads/main. Git đọc file này, theo dõi đến.git/refs/heads/mainđể lấy SHA-1 của commit hiện tại. Khi ở trạng thái detached HEAD, file chứa trực tiếp SHA-1 thay vì reference.
Phần 2: Tìm lỗi sai
🐛 Spot-the-Bug
Tìm lỗi: Corrupted ref gây mất branch
Developer báo cáo branch feature/payment biến mất sau khi máy tính tắt đột ngột. Kiểm tra nội dung .git/refs/heads/feature/payment:
a3f2b7c8d1e4f5a6b7c8d9e0f1a2b3c4d5e6f7g8Câu hỏi: Tại sao ref này bị coi là corrupted?
Đáp án: SHA-1 hash trong Git luôn có đúng 40 ký tự hexadecimal (0-9, a-f). Chuỗi trên chứa ký tự g8 — ký tự g không thuộc hệ hex (chỉ có a-f). Đây là dấu hiệu file bị corrupt khi ghi dở do mất điện.
Khôi phục: Dùng git reflog tìm SHA đúng, hoặc git fsck --lost-found tìm dangling commits, rồi git update-ref refs/heads/feature/payment <correct-sha>.
Phần 3: Bài tập khám phá
Bài tập: Khám phá Git object database
Mục tiêu: Dùng plumbing commands để hiểu cách Git lưu trữ dữ liệu bên trong.
Các bước thực hiện:
mkdir internals-lab && cd internals-lab && git initecho "Hello Git Internals" > hello.txt && git add . && git commit -m "first commit"- Khám phá HEAD chain:
cat .git/HEAD→cat .git/refs/heads/main - Dùng
git cat-file -p <commit-sha>xem commit → tìm tree SHA git cat-file -p <tree-sha>xem tree → tìm blob SHAgit cat-file -p <blob-sha>xem nội dung file gốc- Tự tạo blob:
echo "Manual blob" | git hash-object -w --stdin - Tạo thêm 1 commit, dùng
git cat-file -pxem fieldparent
Kết quả mong đợi: Chuỗi HEAD → branch ref → commit → tree → blob — mọi thứ trong Git đều là object được đánh địa chỉ bằng SHA-1.
Kiến thức nâng cao
Git đang chuyển dần từ SHA-1 sang SHA-256 (bắt đầu từ Git 2.29). Nguyên lý hoạt động giống hệt — chỉ khác hàm hash. Hiểu content-addressable storage là bạn đã nắm được trái tim của Git.