Cách Git lưu trữ dữ liệu
Mình mới xem được một video nói về cách Git lưu trữ dữ liệu nên muốn note lại đây, với mong muốn share đến các bạn cũng như nếu có sai sót gì thì mọi người góp ý giúp nhé.
Git
Là công cụ dùng để lưu trữ các phiên bản khác nhau của một phần mềm, đồng thời nó cũng chứa các lệnh cho phép thực hiện nhiều thao tác khác nhau trên các phiên bản phần mềm. Vậy làm sao để Git có thể lưu trữ được các phiên bản khác nhau của một phần mềm? Dữ liệu đó được lưu như thế nào? Ở đâu và khi nào?
Cách Git lưu trữ dữ liệu
Git lưu dữ liệu dưới dạng key-value, tức là lưu value với key tương ứng và key sẽ được dùng để truy xuất value cho những lần sau (có thể gọi là objects). Nếu đã từng làm việc với Git, chắc chắn bạn đã từng thấy qua sự xuất hiện của folder tên ".git". Tất cả dữ liệu về repo của bạn được Git lưu trong này.
Lưu thử file
Chúng ta sẽ thử lưu một file với Git, bằng cách tạo một git repo: chạy lệnh git init, tạo file hello.txt và viết nội dung "xin chao viblo".
Sau đó gõ lệnh git hash-object -w hello.txt. Git sẽ hash nội dung của file thành key bằng SHA-1, còn phần nội dung được sẽ được nén lại và lưu với key vừa tạo để tiết kiệm bộ nhớ. Lúc này Git sẽ trả cho chúng ta key để lưu nội dung file (hiện trên màn hình d003c91a4f5125666ab2435338171546d3ac9dde)
. Mở ./git/objects, ta thấy folder d0, bên trong có file 03c91a4f5125666ab2435338171546d3ac9dde chứa nội dung đã được zip của file hello.txt.
Chỗ này Git tạo folder d0 là để giảm số lượng file trong một folder xuống, vì một số hệ hành hay ... gì đó chỉ cho phép một số lượng file nhất định được nằm trong một folder, nên nếu bạn lưu với key là abcdef......... thì Git sẽ tạo folder ab và lưu file tên cdef.......
Gõ lệnh git cat-file -p d003c91a4f5125666ab2435338171546d3ac9dde, Git sẽ in ra nội dung của file hello.txt.
Lưu ý chỗ này, Git chỉ mỗi nội dung của file, còn tên thì không và phần dữ liệu như thế được gọi là blob.
Để giải quyết vấn đề về tên file, Git "đẻ" ra một kiểu mới, gọi là tree. Hình dung directory và file thì tree tương ứng directory còn blob tương ứng với file. một tree chứa các tree và blob khác, và cũng được lưu vào folder object. Dữ liệu trong tree được lưu thành nhiều mục (entries), mỗi entry là một tree hoặc blob khác với dữ liệu là Kiểu quyền - loại - hash key - tên.
Commit
Vậy là đến đây Git đã có thể lưu toàn bộ source code của bạn (vì source code gồm các directory và các file, các directory lại chứa các file). Mỗi lần bạn commit, Git sẽ lưu một phiên bản snapshot source code của bạn tại thời điểm đó, bằng cách lưu hashkey của root directory của source của bạn. Chưa đủ git còn lưu thêm các thông tin như parent (commit trước commit này), author, commiter và commit message. Tất cả các thông tin đó ta lại xem là blob và lưu thôi.
Branch
Đến đây là thấy ngon rồi, nhưng mỗi commit đều có một cái mã hash dài ngoằng như aa281777b7767c6fc258687d07850a22259b4230. Thật sự thì chẳng ai muốn nhớ cái chuỗi này cả, vừa khó đọc vừa chẳng “con người” chút nào. Trong khi đó, khi code thì mình chỉ cần chuyển sang commit mới nhất để tiếp tục làm việc thôi, đâu cần phải nhớ cả đống ký tự kia. Và thế là branch xuất hiện. Bạn có thể hình dung branch giống như một cái “nhãn” (ví dụ như feat/login) dễ nhớ, nó luôn trỏ tới commit mới nhất của bạn. Mỗi lần bạn tạo commit mới, branch cũng tự động di chuyển theo. Nhờ có branch, thay vì phải nhớ những mã hash dài dằng dặc, bạn chỉ cần nhớ một cái tên ngắn gọn, dễ hiểu — vừa tiện, vừa gọn, vừa “người” hơn rất nhiều.
All rights reserved