Giới Thiệu Về Git
Git là một hệ thống quản lý phiên bản phân tán giúp theo dõi và quản lý các thay đổi trong mã nguồn. Qua bài viết này, bạn sẽ hiểu rõ về cách mà Git hoạt động, đặc biệt là cách xây dựng chức năng git clone
bằng Javascript.
Nội Dung Chính
- Tổng Quan Về Git
- Tóm tắt các thành phần nội bộ của Git
- Cách lưu trữ blob trong Git
- Cấu trúc tree và commit trong Git
- Chức Năng Git Clone
- Giao thức thông minh của Git
- Tệp gói Git
- Nén delta trong Git
- Quy trình clone trong Git
Tổng Quan Về Mô Hình Hoạt Động Của Git
Mô Hình Hoạt Động Của Git
Git sử dụng ba loại đối tượng chính là blob, tree và commit.
Khi bạn thực hiện lệnh git add
, Git sẽ lưu trữ tất cả các tệp thành blob, tạo ra một đối tượng tree từ các tệp trong thư mục đó. Mỗi tệp sẽ có một blob tương ứng trong mã nguồn làm bản sao làm việc và một chỉ mục đặc biệt cho Git pack.
Khi bạn thực hiện lệnh commit lần đầu tiên, Git sẽ tạo tệp HEAD chứa đường dẫn đến nhánh chính (master). HEAD là con trỏ dành cho nhánh, trong khi đó, nhánh lại chỉ đến commit cuối cùng ở mỗi nhánh.
Từ đó, các nhánh mới sẽ tuân theo cấu trúc đồ thị DAG (Directed Acyclic Graph). Khi bạn ghép các nhánh có parent giống nhau, Git sẽ yêu cầu bạn giải quyết xung đột trước khi thực hiện ghép.
Blob
Mỗi tệp trong thư mục Git được lưu trữ dưới dạng blob, với cấu trúc như sau:
blob <size>\0<content>
Bạn có thể sử dụng lệnh git cat-file
để xem nội dung của blob:
git cat-file -p d8329fc1cc938780ffdd9f94e0d364e0ea74f579
Tệp blob bắt đầu bằng từ khoá blob
, theo sau là độ dài của nội dung trong bytes, một byte null, và cuối cùng là nội dung đã được nén bằng zlib.
Blob sẽ được lưu trữ trong thư mục .git/objects
. Nội dung từ blob đến content (trước khi nén) tạo thành một hash SHA-1 20 bytes được viết dưới dạng 40 ký tự hexadecimal. Hai ký tự đầu tiên được sử dụng làm thư mục và các ký tự còn lại được sử dụng để đặt tên tệp.
Giải thích một số code để viết và đọc đối tượng git blob.
Tree
Đối tượng tree được sử dụng để mã hóa thông tin cấu trúc thư mục.
tree <size>\0
<mode> <name>\0<20_byte_SHA>
<mode> <name>\0<20_byte_SHA>
...
Bạn có thể dùng git cat-file
để xem nội dung của đối tượng tree và sử dụng git write-tree
để viết thư mục hiện tại. Ví dụ để xem nội dung của tree:
git cat-file -p 3c4e9cd789d88d8d89c1073707c3585e41b0e614
Như với đối tượng blob, mỗi tree bắt đầu bằng từ khoá tree
, theo sau là độ dài nội dung trong bytes và một byte null.
Mỗi dòng sau đó đại diện cho một đối tượng trong thư mục. Mỗi mode biểu diễn loại tệp hoặc thư mục dựa trên mã phân quyền tệp Unix (ví dụ: 040000 - thư mục, 100644 - tệp có quyền đọc và ghi).
Cách Đọc và Ghi Tree
Dưới đây là chức năng để đọc và ghi tree bằng Javascript.
javascript
const fs = require("fs");
const zlib = require("zlib");
...
Commit
Commit có cấu trúc như sau:
commit <length>/0
tree \0<20_byte_SHA>
parent? \0<20_byte_SHA>
author <name> <email> <seconds_since_1970> <time_zone>
committer <name> <email> <seconds_since_1970> <time_zone>
<commit message>
Nội dung này bao gồm các thông tin như tác giả, người thực hiện và thông điệp của commit.
Chức Năng Git Clone
Giao Thức Thông Minh Git
Khi sử dụng lệnh fetch, push hay clone, client và server sẽ giao tiếp qua giao thức Git protocol-pack. Giao thức này cho phép xác định dữ liệu mà server có nhưng client không có, từ đó trích xuất dữ liệu khỏi server.
Tệp Gói Git
Sau khi giao tiếp hoàn tất, toàn bộ dữ liệu sẽ được đóng gói trong định dạng tệp gói. Tệp gói bao gồm header và các mục.
Giải Nén Dữ Liệu Delta
Để giải nén và rebuild lại dữ liệu, Git sử dụng thuật toán XDelta. Để tối ưu sự chuyển đổi nội dung giữa các tệp, công nghệ này sẽ so sánh nội dung và áp dụng các lệnh ghép hoặc thêm vào. Quy trình implementación rất chi tiết với các lệnh copy và insert giúp nén file hiệu quả.
Kết Luận
Việc hiểu rõ cấu trúc và cách thức hoạt động của Git không chỉ giúp quản lý tốt phiên bản mã nguồn mà còn nâng cao khả năng viết code hiệu quả bằng JavaScript.
Cảm ơn bạn đã theo dõi bài viết này! Nếu có bất cứ thắc mắc nào, hãy đóng góp ý kiến nhé.
source: viblo